Конструкторы и Деструкторы Конструкторы функции, явно предназначенные для инициализации объектов Деструкторы функция обратная конструктору для обеспечения соответствующей очистки объектов Использование set() приводит к ошибкам. Можно забыть задать начальные значения или сделать это несколько раз class date { date(int, int, int); }; Если для конструктора нужны параметры, они должны задаваться: date today = date(23,6,1983); date xmas(25,12,0); // сокращенная date my_burthday; форма (xmas - рождество) // недопустимо, опущена инициализация Часто бывает хорошо обеспечить несколько способов инициализации объекта класса. Это можно сделать, задав несколько конструкторов class date { int month, day, year; public: date(int, int, int); date(char*); date(int); date(); }; date date date date // // // // день месяц год дата в строковом представлении день, месяц и год сегодняшние дата по умолчанию: сегодня today(4); july4("Июль 4, 1983"); guy("5 Ноября"); now; // инициализируется по умолчанию Один из способов сократить число родственных функций – использовать параметры по умолчанию class date { int month, day, year; public: date(int d=0, int m=0, int y=0); date(char*); // дата в строковом представлении }; date::date(int d, int m, int y) { // проверка, что дата допустимая day=d; month=m; year=y; } Деструкторы - функция обратная конструктору для обеспечения соответствующей очистки объектов class char_stack { int size; char* top; char* s; public: char_stack(int sz){ top=s=new char[size=sz]; } ~char_stack() { delete s; } // деструктор void push(char c) { *top++ = c; } char pop(){ return *--top;} }; Когда объект класса char_stack выходит из области видимости, вызывается деструктор: void f() { char_stack s1(100); char_stack s2(200); s1.push('a'); s2.push(s1.pop()); char ch = s2.pop(); cout << chr(ch) << "\n"; } Если у класса есть конструктор, то он вызывается всегда, когда создается объект класса Если у класса есть деструктор, то он вызывается всегда, когда объект класса уничтожается Объекты могут создаваться как: [1] Автоматический объект: создается каждый раз, когда его описание встречается при выполнении программы, и уничтожается каждый раз при выходе из блока, в котором оно появилось; [2] Статический объект: создается один раз, при запуске программы, и уничтожается один раз, при ее завершении; [3] Объект в свободной памяти: создается с помощью операции new и уничтожается с помощью операции delete; [4] Объект член: как объект другого класса или как элемент вектора. Предостережение: Если x и y - объекты класса cl, то x = y в стандартном случае означает побитовое копирование y в x Такая интерпретация присваивания нежелательному результату может привести к class char_stack { int size; char* top; char* s; public: char_stack(int sz) { top=s=new char[size=sz]; } // конструктор ~char_stack() { delete s; } // деструктор void push(char c) { *top++ = c; } char pop() { return *--top; } }; void h() { char_stack s1(100); char_stack s2 = s1; char_stack s3(99); s3 = s2; } // неприятность Конструктор char_stack::char_stack() вызывается дважды: для s1 и для s3. Для s2 он не вызывается, поскольку эта переменная инициализируется присваиванием. Однако деструктор char_stack::~char_stack() вызывается трижды: для s1, s2 и s3! По умолчанию действует интерпретация присваивания как побитовое копирование, поэтому в конце h() каждый из s1, s2 и s3 будет содержать указатель на вектор символов, размещенный в свободной памяти при создании s1. Не останется никакого указателя на вектор символов, выделенный при создании s3 Это приведет, в лучшем случаю, к краху системы. (Обычно результатом применения delete дважды к одному указателю приводит к бесконечному циклу)