Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология Образование Политология Производство Психология Стандартизация Технологии |
Инициализация объектов класса: конструкторы.
После создания объектов их элементы могут быть инициализированы с помощью конструкторов. Конструктор представляет собой функцию-элемент класса с тем же именем, что и класс. Программист пишет конструктор, который затем автоматически вызывается всякий раз, когда создается объект этого класса. Элементы данных не могут быть инициализированы в определении класса. Элементы данных либо должны инициализироваться в конструкторе класса, либо их значения могут быть установлены позже, после создания объекта. Конструктор не может ни специфицировать тип возвращаемого значения, ни возвращать какое-либо значение. Конструкторы могут быть перегружены, чтобы предусмотреть различные способы инициализации объектов класса. При объявлении объекта класса справа от его имени и до точки с запятой в круглых скобках могут быть заданы инициализаторы. Эти инициализаторы передаются в качестве аргументов в конструктор класса. Скоро мы рассмотрим несколько примеров таких вызовов конструктора После того как класс определен и заданы объекты этого класса, как правило, возникает необходимость выполнения каких-либо действий по инициализации каждого из объектов. При этом для разных классов могут понадобиться различные способы инициализации. Такими действиями могут быть, например, открытие файлов, загрузка драйверов, динамический заказ дополнительной оперативной памяти, присвоение начальных значений элементам данных и т. п. Для выполнения действий такого рода можно было бы воспользоваться какой-либо специально определенной программистом функцией-членом класса, например InitObject или SetObject. Вместе с тем это налагает на программиста дополнительные обязанности, например придется записывать вызов этих функций для каждого вновь определяемого объекта. Преодолеть это неудобство в C++ довольно просто, используя конструкторы классов. Для некоторого класса конструктор - это функция, являющаяся его членом и имеющая имя, совпадающее с именем самого класса, а также не содержащая типа возвращаемого значения. Особенностью этой функции является ее автоматический вызов для каждого из объектов класса в тот момент, когда по естественному ходу выполнения программы встречается описание объекта, например: class Vectors { int А[25], В[25], С[25]; public: Vectors(); void VectorsSum ( Vectors *, Vectors *); // Другие методы }; Vectors:: Vectors() { memset(A, 0, 25); memset(B, 0, 25); memset(C, 0, 25); } main() { Vectors First; // В этом месте будут вызваны Vectors Second; // конструкторы для First и Second. // Операторы программы }
Одним из важных свойств конструктора является его автоматический вызов при описании любого объекта какого-либо класса, использующего конструктор, что снимает с программиста задачу своевременного отслеживания инициализации вновь вводимых объектов. В общем случае конструкторы классов могут иметь списки параметров, которые могут потребоваться при инициализации. При этом программист будет обязан задать список инициализации при описании каждого нового объекта.
Использование с конструкторами аргументов по умолчанию. Конструктор из листинга time.cpp (рис. ) инициализировал hour, minute и second нулевыми значениями (т.е. 12 часами полуночи в военном формате времени). Конструкторы могут содержать аргументы по умолчанию. На рис. 9 конструктор класса Time переопределяется так, чтобы он включал для каждой переменной аргумент с нулевым значением по умолчанию. Задавая для конструктора аргумент по умолчанию, мы гарантируем, что благодаря этим аргументам объект будет находится в корректном состоянии, даже если не будет задано никаких значений при вызове конструктора. Предусмотренный программистом конструктор, все аргументы которого имеют значения по умолчанию, называется также конструктором по умолчанию (он может вызываться без аргументов). Конструктор использует того же рода код проверки допустимости данных, что и функция setTime, чтобы гарантировать, что значение, заданное для элемента hour, находится в диапазоне от 0 до 23 и что значения для каждого из элементов minute и second находятся в диапазоне от 0 до 59. Если значение попадает за пределы диапазона, оно устанавливается в нуль (это - пример обеспечения целостности состояния данных объекта). Конструктор мог бы непосредственно вызывать setTime, однако это привело бы к накладным расходам, связанным с дополнительным вызовом функции. В программе на рис. инициализируются пять объектов класса Time - один со всеми аргументами, принимаемыми по умолчанию при вызове конструктора, один с одним указанным аргументом, один с двумя указанными аргументами, один с тремя указанными аргументами и один с тремя недопустимыми значениями аргументов. Содержание элементов данных каждого объекта после его создания и инициализации отображается на экране. //Файл time.h //Определение класса Time #ifndef TIME_H #define TIME_H class Time { public: Time(int = 0, int = 0, int = 0); void setTime(int, int, int); void printMilitary(); void printStandard(); private: int hour; int minute; int second; }; #endif Рис. 9. Использование конструктора с аргументами по умолчанию. Часть 1 из 3. //Файл time.cpp // Определение элементов-функций для класса Time #include " stdafx.h" #include < iostream.h> #include " time.h" Time:: Time(int hr, int min, int sec) { hour=(hr> =0 & & hr< 24)? hr: 0; minute=(min> =0 & & min< 60)? min: 0; second=(sec> =0 & & sec< 60)? sec: 0; }
void Time:: setTime(int h, int m, int s) { hour=(h> =0 & & h< 24)? h: 0; minute=(m> =0 & & m< 60)? m: 0; second=(s> =0 & & s< 60)? s: 0; } void Time:: printMilitary() { cout< < (hour< 10? " 0" : " " )< < hour< < ": " < < (minute< 10? " 0" : " " )< < minute< < ": " < < (second< 10? " 0" : " " )< < second; } void Time:: printStandard() { cout< < ((hour==0 || hour==12)? 12: hour%12)< < ": " < < (minute< 10? " 0" : " " )< < minute< < ": " < < (second< 10? " 0" : " " )< < second < < (hour< 12? " AM" : " PM" ); } Рис. 9. Использование конструктора с аргументами по умолчанию. Часть 2 из 3. //Программа-тестер #include " stdafx.h" #include < iostream.h> #include " time.h" main() { Time t1, t2(2), t3(21, 34), t4(12, 25, 42), t5(27, 74, 99); cout< < " Constructed with: \n all arguments default: \n"; t1.printMilitary(); cout< < " \n "; t1.printStandard(); cout< < " \nhour specified; minute and second dafaulted: \n "; t2.printMilitary(); cout< < " \n "; t2.printStandard(); cout< < " \nhour and minute specified; second dafaulted: \n "; t3.printMilitary(); cout< < " \n "; t3.printStandard(); cout< < " \nhour, minute and second specified: \n "; t4.printMilitary(); cout< < " \n "; t4.printStandard(); cout< < " \n all invalid values specified: \n "; t5.printMilitary(); cout< < " \n "; t5.printStandard(); cout< < endl; return 0; } Если для класса не определено ни одного конструктора, компилятор создает конструктор по умолчанию. Такой конструктор не выполняет никакой инициализации, поэтому после создания объекта не гарантируется его корректное состояние. Деструкторы. Деструктор - это специальная функция-элемент класса. Имя деструктора состоит из символа тильды ( ~ ), за которым следует имя класса. Такое соглашение о наименовании не противоречит интуиции, поскольку операция тильды является поразрядной операцией дополнения, а в каком-то смысле деструктор является дополнением конструктора. Деструктор класса вызывается автоматически, когда объект класса выходит из области действия. Сам деструктор фактически не разрушает объекта, скорее он выполняет заключительную «приборку», прежде чем системе будет возвращена выделенная объекту память. Деструктор не принимает параметров и не возвращает значения. У класса может быть только один деструктор - перегрузка деструкторов не допускается. Обратите внимание, что мы не определяли деструкторов для представленных до сих пор классов. На самом деле деструкторы редко используются с простыми классами. Далее мы увидим, что применение деструкторов целесообразно для классов, объекты которых содержат динамически выделенную память (например, для массивов и строк). Популярное:
|
Последнее изменение этой страницы: 2016-04-10; Просмотров: 1585; Нарушение авторского права страницы