Требование целостности и корректности объекта означают, что объект – это нечто большее, чем просто переменная. При создании переменной ее инициализация вовсе не обязательна, в то время как создание объекта должно сопровождаться установлением его начального состояния (инициализация данных, резервирование памяти, ресурсов, установление связей и т.д.). Аналогичные обратные действия необходимо выполнить при его уничтожении перед освобождением памяти. С этой целью в классе вводятся специальные методы – конструкторы и деструктор. Их имена совпадают с именем класса. Конструкторов для данного класса может быть сколь угодно много, они отличаются формальными параметрами, деструктор же всегда один и имеет имя, предваренное символом "~". Если конструктор имеет формальные параметры, то в определении переменной-объекта после ее имени должны присутствовать в скобках значения фактических параметров.
//-----------------------------------------------101-01.cpp
// Класс степенного полинома – конструкторы и деструктор
|
|
struct poly{
int n; // степень полинома
double *pd; // динамический массив коэффициентов
poly(){ // "пустой" полином - нулевой степени
n=0; // с нулевым коэффициентом
pd=new double[1];
pd[0]=0;}
poly(int m){ // полином заданной степени
n=m; // с нулевыми коэффициентами
pd=new double[n+1];
for(int i=0;i<=n;i++)
pd[i]=0; }
poly(int n0,double p[]){ // конструктор из массива коэффициентов
load(n0,p); } // используется вспомогательный метод load
poly(poly &T){ // конструктор "объект из объекта"
load(T.n, T.pd); } // (конструктор копирования)
~poly(){ // деструктор
delete []pd; }
Момент вызова конструктора и деструктора определяется временем создания и уничтожения объектов:
для статических и внешних объектов - конструктор вызывается перед входом в main, деструктор - после выхода из main(). Конструкторы вызываются в порядке определения объектов, деструкторы - в обратном порядке;
для автоматических объектов - конструктор вызывается при входе в функцию (блок), деструктор - при выходе из него;
для динамических объектов - конструктор вызывается при выполнении оператора new, деструктор - при выполнении оператора delete.
В Си++ возможно определение массива объектов класса. При этом конструктор и деструктор автоматически вызываются в цикле для каждого элемента массива и не должны иметь параметров. При выполнении оператора delete для указателя на массив объектов его необходимо предварять скобками.
struct poly {....... }; // определение класса
double D[]={1,2,3,4};
poly a,b(6),c(3,D); // Статические объекты – конструкторы
// пустой полином, заданной размерности и из массива
poly *p,*q; // Указатели на объект
void main(){
poly c,d(c); // Автоматические объекты
p = new poly; // Динамический объект
|
|
q = new poly[n]; // Динамический массив объектов
delete p; // Уничтожение динамического объекта
delete []q; // Уничтожение динамического массива объектов
} // Уничтожение автоматических объектов
Замечание: процесс конструирования «вложен» в процесс выделением памяти под переменную. Конструктор вызывается сразу же после выделения памяти, а деструктор – перед ее освобождением.
Безымянные объекты. Программе зачастую требуются «одноразовые» объекты, для которых только и требуется, что передать их на вход функции или метода, либо использовать их в выражении в качестве аналога константы. Такой объект можно создать, указав имя класса и в скобках фактические параметры конструктора.
//-------- Безымянные объекты
struct A{
int a;
A(int a1){a=a1;} // Конструктор
A &INC(){ a++; return *this; } // Метод класса - инкремент
void show(){ printf("%d\n",a); }
};
void F(A bb){ bb.a++; bb.show(); }
void main(){
F(A(5)); // Фактический параметр – безымянный объект
A(2). INC().INC().show();} // Вызов методов для безымянного объекта