Конструкторы и декструкторы

advertisement
Конструкторы и Деструкторы
Конструкторы функции, явно предназначенные для инициализации объектов
Деструкторы функция обратная конструктору для обеспечения соответствующей
очистки объектов
Использование 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 дважды к одному указателю приводит к бесконечному циклу)
Download