2017-07-16 7 views
0

Beim Ausführen des folgenden Codes wird der Konstruktor der Basisklasse zuerst abgeleitet, auch wenn wir zuerst ein Objekt der derivate-Klasse deklarieren.warum der Konstruktor der Basisklasse zuerst aufruft?

#include<iostream> 

using namespace std; 

class base { 
    public: 
    base() 
    { cout<<"Constructing base \n"; } 
    ~base() 
    { cout<<"Destructing base \n"; } 
}; 

class derived: public base { 
    public: 
    derived() 
    { cout<<"Constructing derived \n"; } 
    ~derived() 
    { cout<<"Destructing derived \n"; } 
}; 

int main(void) 
{ 
    derived *d = new derived(); //d is defined ahead of the base class object 
    base *b = d; 
    delete b; 

    return 0; 
} 
+0

Was würden Sie sonst noch erwarten und warum genau? – user0042

+2

Hinweis: Es gibt ein "Basis" ** - Unterobjekt ** innerhalb von "abgeleitet". – StoryTeller

+0

Die Frage ist nicht klar. Können Sie erklären? – MoraRockey

Antwort

4

Vererbung drückt eine „ist-a“ Beziehung, so dass alle Objekte der Klasse derivedbase Objekte der Klasse sind. derived Objekte haben alle Daten und Methoden, die base Objekte tun, plus die Daten und Methoden, die explizit in der Klasse derived deklariert sind.

Es ist durchaus möglich (und üblich) Derived Klassen zu schreiben, die von der Implementierung ihrer Klassen Base abhängen. Angenommen, dass wir

class Base { 
public: 
    Base() { n = 5; } 
    int GetN() const { return n; } 
private: 
    int n; 
}; 

class Derived : public Base { 
public: 
    Derived() { m = GetN() * 2; } 
    int GetM() const { return m; } 
private: 
    int m; 
}; 

Jetzt würden wir

erwarten haben
Derived* d = new Derived(); 
std::cout << d->GetM() << std::endl; 

10 zu drucken, das ist genau das, was es tun sollte (vorbehältlich Fehler meinerseits). Dies ist eine völlig vernünftige (wenn auch etwas gekünstelte) Sache zu tun.

Der einzige Weg, kann der Sprachcode wie diese erhalten richtig funktioniert, ist den Base Konstruktor vor dem Derived Konstruktor ausgeführt werden, wenn ein Objekt vom Typ Derived zu konstruieren. Dies liegt daran, dass der Derived-Konstruktor davon abhängig ist, dass er die GetN()-Methode aufrufen kann, die er von Base erbt, deren ordnungsgemäße Funktion davon abhängt, dass das Datenelement n ordnungsgemäß im Base-Konstruktor initialisiert wurde.

, Zusammengefasst, wenn jedes Derived Objekt konstruieren, C++ muss es als Base erstes Objekt konstruieren, weil Derived ist-ein Base und hängt im allgemeinen darauf Implementierung und Daten sind.

Wenn Sie das tun

base* b = d; 

in Ihrem Code, sind Sie eine Variable b deklarieren, die vom Typ „Zeiger auf ein base Objekt“ ist und dann diese Variable mit der gleichen Speicheradresse Initialisierung in d gehalten. Der Compiler stört das nicht, weil alle derived Objekte ARE base Objekte sind, daher ist es sinnvoll, dass Sie d als b behandeln möchten. Nichts passiert tatsächlich mit dem Objekt hier, es ist einfach eine Deklaration und Instanziierung einer Zeigervariablen. Das Objekt, auf das d zeigt, war bereits ein Objekt base, da alle derived Objekte Basisobjekte sind.

Beachten Sie, dass diese Erklärung absichtlich ein wenig unscharf um die Kanten ist und nicht annähernd eine vollständige Erklärung der Beziehung zwischen Basis und abgeleiteten Klassen in C++ ist. Sie werden nach anderen Artikeln/Büchern/dem Standard dafür suchen. Ich hoffe, dass dies für Anfänger relativ einfach zu verstehen ist.

Verwandte Themen