2010-12-19 11 views
2

Der Child-Konstruktor im folgenden Code ruft seinen übergeordneten Konstruktor auf, um sich selbst zu initialisieren. Der Code wird jedoch erst kompiliert, wenn Child den Grandparent-Konstruktor aufruft, obwohl dies ein Implementierungsdetail ist, das in Parent verborgen sein soll. Ich möchte dieses Detail den Benutzern der Child-Klasse nicht zugänglich machen, da es sich in Zukunft ändern könnte. Wie kann ich den folgenden Code erhalten?Wie vermeiden Sie den Aufruf eines Großelternkonstruktors in C++?

Ich versuchte, die Vererbung auf 'privat' zu ändern, aber der Kind-Konstruktor wurde immer noch über diese private Vereinbarung informiert, die IMHO den Zweck der privaten Vererbung etwas vereitelt!

Irgendwelche Vorschläge?

#include <iostream> 

class MyObject { 
    public: 
    MyObject(int i) { 
     std::cout << "MyObject(" << i << ") constructor" << std::endl; 
    } 
}; 

class Grandparent { 
    public: 
    Grandparent(MyObject i) 
    { 
    }; 
}; 

class Parent: virtual public Grandparent { 
    public: 
    Parent(int j) : 
     Grandparent(MyObject(j)) 
    { 
    }; 
}; 

class Child: virtual public Parent { 
    public: 
    Child() : 
     //Grandparent(MyObject(123)), // Won't work without this 
     Parent(5) 
    { 
    }; 
}; 

int main(void) 
{ 
    Child c; 
    return 0; 
} 
$ g++ -o test test.cpp 
test.cpp: In constructor ‘Child::Child()’: 
test.cpp:29: error: no matching function for call to ‘Grandparent::Grandparent()’ 
test.cpp:12: note: candidates are: Grandparent::Grandparent(MyObject) 
test.cpp:10: note:     Grandparent::Grandparent(const Grandparent&) 
+0

möglich Duplikat von [gcc C++ virtuelles Vererbungsproblem] (http://stackoverflow.com/questions/2126522/gcc-c-virtual-inheritance-problem) –

Antwort

5

Es ist, weil das Erbe virtuell ist. Die virtuelle Vererbung kann niemals ein Implementierungsdetail sein, da die Child-Klasse die Instanzen einer mehrfach geerbten Klasse verwalten muss. Wenn Sie normale Vererbung verwenden, sollte dies kein Problem sein.

+0

Das scheint das Problem zu sein - danke! Irgendwelche Hinweise/Gründe dafür, warum das der Fall ist? – Malvineous

+0

@Malvineous, [Dieser Artikel] (http://www.learncpp.com/cpp-tutorial/118-virtual-base-classes/) ist die beste Erklärung, die ich gefunden habe. Grundsätzlich ist sicherzustellen, dass der virtuelle Basiskonstruktor auch bei mehrfacher Vererbung nur einmal aufgerufen wird (durch die am weitesten abgeleitete Klasse außerhalb der normalen Konstruktorkette). –

+0

@Sergey: Jetzt verstehe ich, warum es so ist - vielen Dank! – Malvineous

1

Es funktioniert gut für mich, wenn die virtuelle Vererbung entfernt wird.

Verwandte Themen