Jest dokładnie na odwrót. Użycie delete zwalnia pamięć i dlatego nie można ponownie użyć operatora delete, przypisanie 0 nie wiem co w zasadzie robi, gdyż nigdy nie zetknąłem się z czymś podobnym, prawdopodobnie w jakiś sposób rezerwuje pamięć i dlatego można ponownie użyć delete.
- Kod: Zaznacz cały
TForm2 *MyForm = new TForm2(this);
MyForm->ShowModal();
delete MyForm;
MyForm = 0;
delete MyForm; // <-- ponowne użycie delete
Jeżeli możliwe jest ponowne użycie delete do usunięcia obiektu z pamięci, to jest logiczne, że ten obiekt musi znajdować się w pamięci.
- Kod: Zaznacz cały
TForm2 *MyForm = new TForm2(this);
MyForm->ShowModal();
delete MyForm;
delete MyForm; // < -- to wywoła błąd, gdyż obiekt MyForm został już usunięty i zwolnił pamięć
w powyższym przykładzie nie można użyć dwukrotnie operatora delete, gdyż obiekt MyForm został już usunięty z pamięci i zwolnił adres, więc operator delete nie może go odnaleźć.
- Kod: Zaznacz cały
TForm2 *MyForm = new TForm2(this);
MyForm->ShowModal();
delete MyForm;
MyForm = 0;
MyForm->ShowModal();
Powyższy kod wywoła komunikat błędu: Acces violation at address 00401A94 in module "Project1.exe". Read of address 00000000
- Kod: Zaznacz cały
TForm2 *MyForm = new TForm2(this);
MyForm->ShowModal();
delete MyForm;
MyForm->ShowModal();
A ten kod zaowocuje komunikatem błędu: Acces violation at address 00000000. Read of address 00000000
To chyba najdobitniej świadczy o tym, że operator delete zwalnia adres w pamięci, a przypisanie oknu wartości 0 umieszcza okno pod jakimś adresem.
Użycie
Form2 = 0 wydaje mi się mieć tylko uzasadnienie w sytuacji gdy nie niszczysz obiektu za pomocą operatora delete, lecz gdy obiekt sam siebie niszczy w zdarzeniu OnClose, czyli umieszczasz kod niszczenia obiektu i zwalniania pamięci w zdarzeniu OnClose formularza bazowego, np:
na Form1 wywołujesz MyForm w oparciu o klasę bazową TForm2:
- Kod: Zaznacz cały
TForm2 *MyForm = new TForm2(this);
MyForm->Show(); // nie musi być modalne
następnie w klasie bazowej w zdarzeniu OnClose formularza Form2 umieszczasz taki kod:
- Kod: Zaznacz cały
//---------------------------------------------------------------------------
void __fastcall TForm2::FormClose(TObject *Sender, TCloseAction &Action)
{
Action = caFree;
Form2 = 0;
}
//---------------------------------------------------------------------------
Kolejna ciekawostka, jeżeli np. w zdarzeniu OnClick przycisku Button1 umieścisz taki kod:
- Kod: Zaznacz cały
TForm2 *MyForm = new TForm2(this);
MyForm->Show(); // nie musi być modalne
i klikniesz na niego np 3 razy, to zostaną utworzone 3 na pozór identyczne okna, jednak będą się różniły nazwą formularz, czyli będą miały kolejne nazwy: Form2, Form2_1, Form2_2, itd...
Jak to sprawdzić. Umieść na formularzu Form2 obiekt Label1, a następnie w zdarzeniu OnClick przycisku Button1 na formularzu Form1 umieść taki kod:
- Kod: Zaznacz cały
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TForm2 *MyForm = new TForm2(this);
MyForm->Show();
MyForm->Label1->Caption = MyForm->Name;
}
//---------------------------------------------------------------------------
Dzięki temu, że program sam zmienia nazwy kolejnych okien możesz się odwoływać do kolejnych okien po ich różnych nazwach. Jeżeli umieścisz do tego podany wyżej kod w zdarzeniu OnClose formularza bazowego, nie będziesz musiał się martwić wyciekiem pamięci, gdyż okn przy zamknięciu zawsze zwolni pamięć.