Форум — Ответы     (  К темам )
 ?  Георгий: о вложенных классах (06-05-2003 18:22:45)
есть
class N
{
public:
AnsiString M;
};
N* n=new N;
delete n;
будет ли в этом случае вызван деструктор AnsiString?
 Andrew (07-05-2003 10:46:39)
Деструктор для AnsiString вроде как всегда сам неявно вызывается.

Конкретно в твоем примере по отношению к AnsiString не знаю, в отладчике так глубоко не заходил, но у меня так все работает и CodeGuard ничего не замечает.

А в общем случае если созданный класс наследуется от TComponent и вложенные классы от TComponent и при создании у них в Owner задан главный класс, то он удалит их сам, Иначе в деструкторе главного класса надо делать delete всех вложенных.
 Alexander (07-05-2003 13:07:50)
Для VCL-style классов экземпляры надо заводить через new, соотв. и удалять через delete. Если же, как здесь, конструктор вызывается по ссылке, то и деструктор также вызывается автоматически.
Внимание, это в BCB. В некоторых других C++ — компиляторах не вызывается конструктор для полей по ссылке.
 Andrew (07-05-2003 19:17:48)
Если подчиненные классы не VCL или Основной не VCL или Owner не задан деструктор не вызывается, только ручками звать приходится. Проверенно.
 Matt (07-05-2003 23:07:29)
А можно просто напросто ПЕРЕОБЪЯВИТЬ деструктор ~M так, что-бы он звал MessageBox, и посмотреть.
Вообще-то должен вызываться, иначе M будет д-о-о-о-о-лго висеть в памяти(хотя это еще и от ОС зависит).

Хотите пример на эту тему?
Смотрите:

class N
{
public:
AnsiString M;
~N(){MessageBox(0,"вызван N-destructor","вызван N-destructor",0);};
};

class N1:public N{
public:
AnsiString M1;
AnsiString M2;
AnsiString M3;
~N1(){MessageBox(0,"вызван N1-destructor","вызван N1-destructor",0);};
};

N* n=new N1;
delete n;

Не поленитесь создать новый проэкт и кинуть на форму кнопку!
Повесте этот код на на кнопку Button1.
Компильните прогу и ткните эту кнопку.
На палубу вылезет MessageBox вопящий о том, что вызван
деструктор ~N для переменной n, который успешно прикончил M.
Стоп!!!
А когда уничтожились M1,M2,M3????
А никогда!!!
Тупому существу под названием "Компилятор" не приходит в голову, что
два объекта "одного" класса имеют РАЗНЫЙ РАЗМЕР!
Правда, слава ООП, эта проблема легко разрешима: достаточно оба деструктора объявить виртуальными:

class N
{
public:
AnsiString M;
virtual ~N(){MessageBox(0,"вызван N-destructor","вызван N-destructor",0);};
};

class N1:public N{
public:
AnsiString M1;
AnsiString M2;
AnsiString M3;
virtual ~N1(){MessageBox(0,"вызван N1-destructor","вызван N1-destructor",0);};
};

N* n=new N1;
delete n;

Вот теперь все хорошо...
Сначала вызывается деструктор производного класса,~N1,а затем и базового, ~N.
Этот и другие интересные ньюансы С++ разбираются в книге Дж. Элджера.
Прочтите не пожалеете.
 Георгий (08-05-2003 00:20:32)
всем спасибо:
Andrew: AnsiString  — не класс VCL и у него нет родителей.
Alexander: а у каких компиляторов не вызывается деструктор вложенного класса?
Matt: хорошая идея, но я не о полиморфизме спрашивал, тем более, что код на котором ты демонстрируешь не корректную работу не является не корректным — при таком обьявлении считается, что наследник сам работает со всеми данными предка включая их деинициализацию.

на основе вышеизложеного следующий код является эквивалентом кода, вызвавшего вопрос:

class A
{
public:
A(){Form1->Memo1->Lines->Add("A");};
~A(){Form1->Memo1->Lines->Add("~A");};
};
class B
{
public:
A a;
B(){Form1->Memo1->Lines->Add("B");};
~B(){Form1->Memo1->Lines->Add("~B");};
};
void __fastcall TForm1::Button1Click(TObject *Sender)
{
A* a;
Form1->Memo1->Lines->Add("создаём A");
a=new A;
Form1->Memo1->Lines->Add("удаляем A");
delete a;
B* b;
Form1->Memo1->Lines->Add("создаём B");
b=new B;
Form1->Memo1->Lines->Add("удаляем B");
delete b;
}

то, что этот код выводит в Memo1 подтверждает слова Alexander`а
 Andrew (08-05-2003 09:58:35)
я знаю что AnsiString — не класс VCL и у него нет родителей, поэтому я в начале написал индивидуально про него, а после описал более общий случай с VCL, не-VCL и заданием владельца
 Георгий (08-05-2003 13:07:56)
Ё моё значит в конец пред. поста добавляю:
"и Andrew"
PS. С наступающими и прошедшими
 Andrew (08-05-2003 13:49:38)
Спасибо, тем более у меня 9-го день рождения :)