Инструменты пользователя

Инструменты сайта


examination:oop:question37

Деструктор можно вызвать и напрямую, не прибегая к оператору delete, поскольку это такая же функция, как и все остальные. class Foo { public: ~Foo(); }; Foo* f = new Foo; f→Foo::~Foo();

в интернете нихера нет,потом поищу ещё ←—Сафин, гуглить научись


Вызов деструктора

Вызов деструктора для объекта абстрактного типа производится автоматически при его выходе из области существования. Для локальных переменных деструктор вызывается при выходе из блока, в котором эта переменная была объявлена. Для глобальных переменных вызов деструктора является частью процедуры завершения программы, выполняемой после функции main(). Выход указателя на объект абстрактного типа из области существования этого указателя не приводит к вызову деструктора для объекта, на который он указывает. Надо различать указатели на объект, созданные при помощи операции new, и другие объекты. Рассмотрим пример с указателем на автоматический объект абстрактного типа:

class cl{int num; 
     public: 
     cl (int i){num = i;} 
     ~cl (){} 
     };
void main (){ 
     // Создание объекта obj типа cl: 
     cl obj (1); 
     // Создание указателя ptr на объект класса cl и его инициализация 
     // адресом, создаваемой здесь же безымянной переменной типа cl: 
     cl *ptr = &cl (2); 
     {// Указатель в блоке относится к тому же объекту, что и ptr. 
     cl *tmp = ptr; 
     } 
     }

В этом случае как конструктор, так и деструктор будут вызываться дважды. Сначала вызывается конструктор для объекта obj, затем конструктор для безымянного объекта, на который указывает ptr. При выходе из внутреннего блока указатель tmp теряется, однако сам объект сохраняется. При завершении main () в первую очередь вызывается деструктор для бе-зымянного объекта, а затем - деструктор для obj.

Если указатель относится к объекту абстрактного типа, созданному динамически, то деструктор для него вызывается в операции delete:

class cl{int num; 
     public: 
     cl (int i){num = i;} 
     ~cl (){cout<<"Деструктор класса cl. \n "; 
     }; 
 
void main (){ 
     cl *ptr = new cl (1); 
     ... 
     delete ptr; 
     }

Перед удалением из памяти объекта, на который указывает ptr, для него будет вызван деструктор. В результате на экране появится строка Деструктор класса cl. Вызов деструктора можно осуществить явно по его полному имени:

class cl{int num; 
     public: 
     cl (int i){num = i;} 
     ~cl(){} 
     };
void main(){cl obj (1); 
     cl *ptr = &cl (2); 
     obj.cl::~cl (); 
     ptr -> cl::~cl (); 
     }
 

Так же можно вызвать деструктор и для динамического объекта.

cl *ptr = new cl (1); 
     ptr -> cl::~cl ();
 

Отметим, что явный вызов деструктора не отменяет его автоматический вызов.

class X{ int *ip; 
     public: 
     X (int y){ip = new int(y);} 
     ~X(){cout <<"Деструктор класса X;\n"; 
     delete ip;} 
     };
void main(){ X *xp = new X(5); 
     xp->X::~X();	// Явный вызов деструктора. 
     delete xp;	 // Вызов деструктора из delete. 
     }
 

В результате получим два сообщения, если не произойдёт зацикливания при повторной операции delete, применённой к одному и тому же указателю ip:

Деструктор класса X; Деструктор класса X; Пользоваться явным вызовом деструктора надо очень осторожно.

examination/oop/question37.txt · Последние изменения: 2014/01/15 12:22 (внешнее изменение)