Форум — Ответы ( К темам )
? | Георгий: о вложенных классах (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-го день рождения :)
|