Курс ООП в С презентация. ООП в с++(полный курс). Объекты и классы
Скачать 1.76 Mb.
|
ДеструкторыСвойства деструктора:
не наследуется; не может быть объявлен как const или static (см. далее); может быть виртуальным (см. далее). Если деструктор явным образом не определен, компилятор автоматически создает пустой деструктор. Описывать в классе деструктор явным образом требуется в случае, когда объект содержит указатели на память, выделяемую динамически — иначе при уничтожении объекта память, на которую ссылались его поля-указатели, не будет помечена как свободная. Указатель на деструктор определить нельзя. ДеструкторыДеструктор для рассматриваемого примера будет выглядеть так: //реализация деструктора для экземпляра класса person::person() { delete [] name; } Без необходимости явно вызывать деструктор объекта не рекомендуется. Методы классов Методы классовИмя метода-модификатора принято предварять строкой "set_", указывающей проектировщику на то, что этот метод предназначен для изменения значения соответствующего атрибута объекта (например, метод set_name() для атрибута name). Обычно такие методы не возвращают никаких значений, или же возвращают значение кода, указывающее на успешность выполнения операции. //реализация метода, изменяющего имя человека void person::set_name(char* value) { //выделяем память под новую строку: name = new char[strlen(value)+1]; //копируем эту строку в область памяти strcpy(name, value); } Задача этих методов состоит в том, чтобы переложить логику работы с атрибутами на класс. Именно класс должен обеспечивать выполнение правил работы со своими атрибутами. Так, приведенный выше код говорит о том, что изменение имени предполагает не побитовое копирование указателей на строку, а копирование самой строки, находящейся по соответствующему адресу. В случае же использования открытого атрибута любой клиент класса вправе делать со значением атрибута все, что угодно. Методы классовИмена методов-селекторов предваряют строкой "get_", обозначающей получение ими значений атрибутов объекта. Эти методы используют для возвращения значений скрытых атрибутов объекта и вычисления связанных с ними показателей (см. пример выше). //реализация метода, возвращающего имя человека const char* person::get_name() const { return name; } Методы классовМетоды-итераторы позволяют выполнять некоторые действия для каждого элемента определенного набора данных. Эти действия должны быть независимы от структуры данных, и задаваться не одним из методов объекта, а произвольной функцией пользователя. Итератор можно реализовать, если эту функцию передавать ему через указатель на функцию. Обратим внимание на то, что мы не стали описывать в классе метод, отвечающий за ввод/вывод информации о человеке на консоль. Взаимодействие объекта с консолью лучше вынести либо в отдельный класс диалога с пользователем (еще один пример абстракции поведения), либо в независимые от объектов функции. Рассмотрим в этой связи работу с группой объектов. Методы классовСоздадим класс group, который будет включать в себя массив из 10 экземпляров класса person и метод for_each()– итератор для этой группы объектов. Отметим сразу, что означенный массив приведен в виде простого атрибута на диаграмме класса group только для наглядности, ибо подобную реализацию принято представлять на диаграмме как атрибут связи между экземплярами классов. Ради удобства записи дадим новое имя FP типу указателя на функцию, которая не возвращает значения и принимает в качестве аргумента объект типа person: typedef void(*FP)(person&); class group { public: void for_each(FP); private: person Persons[10]; }; Методы классовРабота итератора заключается в последовательном переборе всех элементов группы и применении к ним любой функции, переданной посредством указателя: void group::for_each(FP fp) { for (int i = 0; i < 10; i++) { fp(Persons[i]); } } Методы классовТеперь опишем в основной программе пару независимых от объектов функций, которые требуется применять к объектам типа person, описанным в классе group: void show_name(person& argname) { //передача строки с именем в стандартный поток вывода cout: cout << argname.get_name() << endl; } void set_name(person& argname) { char n[20]; //получение строки с именем из стандартного поток ввода cin: cout << "Enter name: " << endl; cin >> n; argname.set_name(n); } Такие функции называются свободными подпрограммами. Они исполняют роль операций высокого уровня над объектом или объектами одного или разных классов, и группируются в соответствии с классами, для которых они создаются. Это дает основание называть такие пакеты процедур утилитами класса. |