27 Деструкторы: запуск, виртуальные деструкторы, exit и деструкторы.

Деструктор класса вызывается для освобождения элементов объекта до разрушения самого объекта. Деструктор представляет метод с именем, совпадающим с именем класса, перед которым стоит символ тильда (~ ). Деструктор не может принимать параметров, а также не имеет объявленных типа возврата и значений.

class Х

{

public:

~Х();   //деструктор класса Х

};

Если деструктор не объявлен для класса явно, компилятор ге­нерирует его автоматически.

Запуск деструкторов.

Вызов деструктора выполняется неявно, когда переменная выходит из своей объявленной области действия. Для локальных переменных деструкторы вызываются, когда перестает быть активным блок, в котором они объявлены. В случае глобальных перемен­ных деструкторы вызываются как часть процедуры выхода после main.

Когда указатели объектов выходят за пределы области действия, неявный вызов деструктора не происходит. Это значит, что для разрушения  такого объекта операция delete должна быть задана явно.  Деструкторы вызываются строго в обратной последовательно­сти вызова соответствующих конструкторов.

ехit и деструкторы

При вызове abort из программы деструкторы не вызываются, даже для переменных глобальной области действия.

Деструктор может быть также вызван явно одним из двух сле­дующих способов: косвенно, через вызов delete, или прямо, заданием полностью уточненного имени деструктора, delete можно ис­пользовать для разрушения объектов, для которых память распределялась при помощи new. Явный вызов деструктора необходим только в случае объектов, которым распределялся конкретный адрес памяти при помощи new.   

class X {

~X();

};

void* operator new(size_t size, void *ptr)

{

return ptr;

}

char butter[sizeof(x)];

main()

{

 X* pointer=new X;

 X* exact_pointer;

 exact_pointer=new(&buffer) X;  //указатель инициализируется адресом буфера

 

 delete pointer;   //delete разрушает указатель

 exact_pointer->X::~X();   //прямой вызов для отмены распределения памяти

}

Виртуальные деструкторы.

Деструктор может быть объявлен как виртуальный. Это позволяет указателю объекта базового класса вызывать необходимый деструктор в случае, когда указатель фактически ссылается на объект производного класса. Деструктор класса, производного от класса с виртуальным деструктором, сам является виртуальным.

class color

{

public:

virtual ~со1ог(); //виртуальный деструктор для color

};

class red : public color

{

public:

~red(); //деструктор для red также является виртуальным

};

class brightred :public red

{

public:

~brightred();   // деструктор для brightred также  виртуальный

};

Ранее перечисленные классы и следующие объявления:

color *palette[3];

palette[0]=new red;

palettei1]=new brightred;

palette[2]=new color;

дадут такие результаты:

delele palette[0];

// Вызывается деструктор для red после которого

// вызывается деструктор для color

delete palette[1l;

//Первым вызывается деструктор для brightred, за ним

//~red и ~color

delete palette[2];

//Запуск деструктора для color

Однако если ни один из деструкторов не был объявлен вирту­альным, delete palette[0], delete palette[1] и  delete palette[2] вызывают только деструктор для класса со1оr&. Это приведет к непра­вильному разрушению первых двух элементов, которые фактически имели тип red и brightred.

Hosted by uCoz