Dziedziczenie C ++ Constructor / Destructor
EDIT: Podsumowanie odpowiedzi
Poniżej B jest podklasą A.
To kwestia terminologii; lekarze i lekarze sąnie odziedziczony, w tym sensie, że ctor / dtor B będzienie być wypożyczonym z interfejsu A. Klasa ma co najmniej jeden konstruktor i ma dokładnie jeden destruktor.
Konstruktorzy:B nie dziedziczy konstruktorów z A;Chyba że agent B w sposób oczywisty dzwonijeden z Ctor A, domyślny ctor z A zostanie automatycznie wywołanyprzed Korpus ctor B (idea polega na tym, że A musi zostać zainicjalizowany przed utworzeniem B).Destruktory:B nie dziedziczy dtor A;Po wychodzi, destruktor B automatycznie wywoła destruktor A.Podziękowanie: Chciałbym szczególnie podziękować Oli'owi Charlesworthowi i Kosowi za ich odpowiedzi. Postawiłem odpowiedź Kosa jako rozwiązanie, ponieważ najlepiej zrozumiałem.
ORYGINALNY POST
Podczas wyszukiwania w serwisie Google „witryny dziedziczenia C ++ destructor: stackoverflow.com” znajdują się obecnie następujące posty:
Konstruktor i dziedziczenie Destructor: dwóch użytkowników z reputacją 30k + mówi, że jest dziedziczona, a nie jestCzy wirtualne destruktory są dziedziczone?: tutaj nie wspomniano nic, co wskazywałoby na brak dziedziczenia destruktorówDestruktory i dziedziczenie w C ++?: Komentarze wydają się wskazywać, że destruktory są dziedziczoneP1: Z praktyki wiem też, że nie można zainicjować obiektu pochodnego z tym samym prototypem, co konstruktor nadrzędny, nie definiując jednoznacznie konstruktora dla klasy pochodnej, czy to prawda?
Nawet jeśli z postów, które wydają się dziedziczone, wynika, że destruktory wydają się dość oczywiste, wciąż jestem zdziwiony faktem, że użytkownik o reputacji 32 tys. Napisałem mały przykład, który powinien wyjaśnić wszystkim:
#include <cstdio>
/******************************/
// Base class
struct A
{
A() { printf( "\tInstance counter = %d (ctor)\n", ++instance_counter ); }
~A() { printf( "\tInstance counter = %d (dtor)\n", --instance_counter ); }
static int instance_counter;
};
// Inherited class with default ctor/dtor
class B : public A {};
// Inherited class with defined ctor/dtor
struct C : public A
{
C() { printf("\tC says hi!\n"); }
~C() { printf("\tC says bye!\n"); }
};
/******************************/
// Initialize counter
int A::instance_counter = 0;
/******************************/
// A few tests
int main()
{
printf("Create A\n"); A a;
printf("Delete A\n"); a.~A();
printf("Create B\n"); B b;
printf("Delete B\n"); b.~B();
printf("Create new B stored as A*\n"); A *a_ptr = new B();
printf("Delete previous pointer\n"); delete a_ptr;
printf("Create C\n"); C c;
printf("Delete C\n"); c.~C();
}
i tutaj jest wyjście (skompilowane z g ++ 4.4.3):
Create A
Instance counter = 1 (ctor)
Delete A
Instance counter = 0 (dtor)
Create B
Instance counter = 1 (ctor)
Delete B
Instance counter = 0 (dtor)
Create new B stored as A*
Instance counter = 1 (ctor)
Delete previous pointer
Instance counter = 0 (dtor)
Create C
Instance counter = 1 (ctor)
C says hi!
Delete C
C says bye!
Instance counter = 0 (dtor) // We exit main() now
C says bye!
Instance counter = -1 (dtor)
Instance counter = -2 (dtor)
Instance counter = -3 (dtor)
P2: Czy ktoś, kto uważa, że nie jest dziedziczony, może to wyjaśnić?
P3: Co więc się dzieje, gdy wywołujesz konstruktor podklasy z wejściami? Czy nazywa się także „pusty konstruktor” superklasy?