Описание классов(class, struct, union).
⇐ ПредыдущаяСтр 2 из 2 Структура состоит из набора полей, которые никак не защищены. Если элементы структуры имеют переменную длину, их представляют в виде указателей. Выделение и освобождение памяти под эти указатели делаются вручную.
struct Array { double* val; int len; }; void FreeArray(const struct Array*); void AllocArray(const struct Array*, int len); double Elem(const struct Array*, int i); void ChangeElem(const struct Array*, int i, double x);
В отличие от типа структура (struct) языка Си, состоящей только из полей, класс (class) Си++ состоит из полей и функций-членов (member functions). Поля бывают публичными (public), защищёнными (protected) и собственными (приватными, private). В Си++ тип структура аналогичен типу класс, отличие в том, что по умолчанию поля и функции-члены у структуры публичные, а у класса - собственные. class Array { public: void Alloc(int new_len); void Free(); inline double Elem(int i); inline void ChangeElem(int i, double x); protected: int len; double* val; };
Union - представляет собой структуру, члены которой расположены по одному и тому же адресу. Поэтому размер объединения равен размеру его наибольшего члена. В любой момент времени объединение хранит значение только одного из членов.
union Some { int i; double a; }; Вложенные классы. Вложенные классы - это обычные классы, члены которых имеют полный доступ ко всем членам родителя (слово 'родитель' следует понимать не в плане наследования, а в плане непосредственной принадлежности). Объявляются вложенные классы внутри тела родителя, при этом важна область видимости, в которой класс был объявлен. Через объект родительского класса доступ к членам вложенного класса возможен (при наявности допустимых прав) через оператор ::. Главное преимущество вложенных классов заключается в том, что не засоряется глобальная область видимости - если необходима структура или класс для внутреннего хранения данных, то лучшего, чем вложенный класс трудно придумать. В связи с этим и главная рекомендация - вложенными делайте только те классы, которые логически тесно связаны с родительским классом. Нерекомендуемо сильно развивать иерархию вложенных классов, т.к. это ухудшает читаемость - Вы получите механизм обращения типа A::A1::A2::, а это как правило не способствует упрощению понимания логики программы.
Определение объектов при помощи классов. Объекты могут создаваться несколькими способами. Некоторые объекты являются локальными переменными, другие – глобальными, третьи – членами классов. Конструкторы инициализируют объект, другими словами они создают среду, в которой работают функции-члены. Иногда создание такой среды подразумевает захват каких-то ресурсов, таких как файл, блокировка или память, которые должны быть освобождены после их использования. Конструктор локальной переменной вызывается каждый раз, когда управление передается инструкции, содержащей объявление этой локальной переменной.
Конструкторы и деструкторы классов. Объекты могут создаваться несколькими способами. Некоторые объекты являются локальными переменными, другие – глобальными, третьи – членами классов. Конструкторы инициализируют объект, другими словами они создают среду, в которой работают функции-члены. Иногда создание такой среды подразумевает захват каких-то ресурсов, таких как файл, блокировка или память, которые должны быть освобождены после их использования. Конструктор локальной переменной вызывается каждый раз, когда управление передается инструкции, содержащей объявление этой локальной переменной. Для объекта создаваемого в свободной памяти, вызывается конструктор класса, указанного в операторе new. Деструкторы используются для уничтожения объектов. Они очищают память и освобождают ресурсы. Деструкторы вызываются неявно, когда автоматическая переменная выходит из области видимости, удаляется объект, хранящийся в свободной памяти.
Атрибуты доступа к компонентам классов. Управление доступом. Метка public разделяет тело класса на две части. Имена в первой (private) части могут использоваться только функциями-членами. Вторая часть образует открытый интерфейс объектов класса. Структура, на самом деле, является классом, члены которого открыты по умолчанию. Ограничение доступа к структуре данных явно объявленных списком функций имеет несколько преимуществ. В частности, если мы изменим представление класса, нам потребуется только изменить функции-члены, чтобы воспользоваться новым представлением. Код пользователя непосредственно зависит только от открытого интерфейса, и код не потребуется переписывать. Защита закрытых данных базируется на ограничении использования имен членов класса. Эту защиту можно обойти манипулированием с адресами и путем явного преобразования типа.
Объявление и определение методов класса. Любой класс в языке С++ состоит из двух частей: объявления и определения. В объявлении класса говорится, каков интерфейс класса, какие методы и атрибуты составляют объекты этого класса. Объявление класса состоит из ключевого слова class, за которым следует имя класса, список наследования и затем в фигурных скобках - методы и атрибуты класса. Заканчивается объявление класса точкой с запятой. Определение класса должно быть только одно, и если класс используется во многих файлах, его удобно поместить в отдельный файл. В остальных файлах для того, чтобы использовать класс Book, например определить переменную класса Book, в начале файла необходимо поместить объявление класса.
Вызов членов класса. class XXX { public: long x1; int x2; /*Данные-члены класса.*/ long getVal1() {return x1;} long getVal2() {return x2*x1;} /*Функции-члены класса без параметров.*/ int getVal3(int param) {return x2*param;} char* getVal4(char *str) {return str;} /*Функции-члены класса с параметрами.*/ static int f1() {return 100;} static int f2() {return 10;} static int f3(int param) {return param;} /* Определение различных статических функций*/ XXX(long val1, int val2){x1 = val1; x2 = val2;}
/*Конструктор.*/ }; void main() { XXX q(1,2);/* Определение объекта.*/ XXX* pq = new (XXX); pq->x1 = 100; pq->x2 = 100; /*Определение и инициализация объекта по указателю.*/ long (XXX::*fp_0) (); /*Указатель на функцию-член класса.*/ long (XXX::*fp_1) () = &XXX::getVal1; /* Проинициализированный указатель на функцию-член класса. Его значение является относительной величиной и равняется значению смещения функции-члена относительно первого члена класса. */ fp_0 = XXX::getVal1; /* Инициализация первого указателя. Один и тот же указатель можно настраивать на различные функции-члены класса. Главное, чтобы у всех этих функций-членов совпадали списки параметров и возвращаемые значения функций. */ long val_1 = (q.*fp1)(); /*Вызов функции-члена класса по указателю из объекта.*/
long val_2 = (pq->*fp0)(); /* Вызов функции-члена класса по указателю с помощью указателя на объект. */ int (XXX::*fp_3) (int) = &XXX::getVal3; /* Проинициализированный указатель на функцию-член класса. С параметрами типа int. */ int val_3 = (q.*fp_3)(6); /* Вызов функции-члена класса по указателю из объекта с передачей параметров. */ char* (XXX::*fp_4) (char) = &XXX::getVal3; /* Проинициализированный указатель на функцию-член класса с параметрами типа int. */ char val_4 = (pq->*fp4)("new string"); /* Вызов функции-члена класса по указателю с помощью указателя на объект. */ int (*fp_5) () = &XXX::f1; /* Указатель на статическую функцию объявляется без спецификации класса. Явная спецификация класса необходима лишь при инициализации указателя. */ int retval = (*fp_5)(); /*Вызов статической функции по указателю.*/ fp_5 = XXX::f2; /* Перенастройка статического указателя. Главное требование - совпадение списков параметров и типа возвращаемого значения. */ int (*fp_6) (int) = &XXX::f3; /*Указатель на статическую функцию с параметрами.*/ int retval = (*fp_6)(255); /*Вызов статической функции с параметрами по указателю.*/ long (XXX::*px1) = &XXX::x1; /*Определили и проинициализировали указатель на член класса long*/ q.*px11 = 10; /*Используя указатель на компоненту класса, изменили значение переменной x1 объекта q, представляющего класс XXX. */ pq->*px11 = 10; /*Используя указатель на компоненту класса, изменили значение переменной x1 объекта, представляющего класс XXX и расположенного по адресу pq. */ }
Воспользуйтесь поиском по сайту: ©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|