Zakładając, że nie jest wirtualny/wielokrotne dziedziczenie (który komplikuje trochę), to zasady są proste:
- Pamięć obiekt przeznaczono
- Konstruktor klas bazowych są wykonywane, kończąc większość pochodzi
- inicjalizacja element jest wykonany
- przedmiotem staje się prawdziwym przykładem swojej klasie
kod
- Konstruktor jest wykonywany
Należy pamiętać, że do kroku 4 obiekt nie jest jeszcze instancją jego klasy, ponieważ zyskuje ten tytuł dopiero po rozpoczęciu wykonywania konstruktora. Oznacza to, że jeśli wystąpi wyjątek wygenerowany podczas konstruktora elementu, destruktor obiektu nie jest wykonywany, ale tylko już skonstruowane części (np. Członkowie lub klasy bazowe) zostaną zniszczone. Oznacza to także, że jeśli w konstruktorze elementu lub klasy bazowej wywołasz dowolną funkcję obiektu wirtualnego obiektu, wywoływana implementacja będzie podstawową, a nie pochodną. Inną ważną rzeczą do zapamiętania jest to, że członek wymieniony na liście inicjalizacyjnej zostanie skonstruowany w kolejności, w jakiej są zadeklarowani w klasie, a nie w kolejności, w jakiej pojawiają się na liście inicjalizacyjnej (na szczęście wystarczająca liczba najbardziej przyzwoitych kompilatorów wyświetli ostrzeżenie, jeśli umieścisz listę członkowie w innej kolejności niż deklaracja klasy).
Należy również zauważyć, że nawet jeśli w trakcie wykonywania kodu konstruktora obiektu this
już zyskał swoją ostateczną klasy (np w odniesieniu do wirtualnego wysłania) destruktor klasy nie będzie można nazwać chyba konstruktor kończy wykonanie . Dopiero wtedy, gdy konstruktor zakończy wykonywanie, instancja obiektu jest prawdziwym obywatelem pierwszej klasy między instancjami ... zanim ten punkt będzie tylko "instancją wanna-be" (pomimo posiadania odpowiedniej klasy).
Zniszczenie odbywa się w dokładnej kolejności odwrotnej: najpierw destruktor obiektu jest wykonywany, następnie traci swoją klasę (tj. Od tego punktu obiekt jest uznawany za obiekt bazowy), następnie wszystkie elementy są niszczone w kolejności odwrotnej deklaracji, a na końcu proces niszczenia klasy bazowej jest wykonywany aż do najbardziej abstrakcyjnego rodzica. Jeśli chodzi o konstruktora, jeśli wywołasz dowolną funkcję obiektu wirtualnego obiektu (bezpośrednio lub pośrednio) w destruktorze podstawowym lub pręcie, wykonywana implementacja będzie macierzystą, ponieważ obiekt stracił tytuł klasy po zakończeniu destruktora klasy.
Twój przykład może być bardziej wyjaśniający, jeśli twoja wiadomość dla destruktora różni się od twojej wiadomości dla konstruktora. Co też robią 'std :: sort'? – Tom
Ponadto, podczas eksperymentów, porównaj konstrukcję i zniszczenie 'B b',' B * b = new B(); usuń b; 'i' A * a = new b(); delete a; '(Porównaj co się dzieje, gdy używasz słowa' virtual' dla twojego destruktora, np. 'virtual ~ A() {cout <<" A-tor "<< endl;}') – Tom
@Tom, jesteś dobrze. Usuwanie błędów kompilatora. – iammilind