Ein Freund und ich hatten eine sehr interessante Diskussion über die Konstruktion von Objekten, die mit diesem Code endete:
#include
class Parent {
public:
Parent( ) {
this->doSomething( );
}
virtual void doSomething( ) = 0;
};
class Child : public Parent {
int param;
public:
Child( ) {
param = 1000;
}
virtual void doSomething( ) {
std::cout << "doSomething( " << param << " )" << std::endl;
}
};
int main( void ) {
Child c;
return 0;
}
Ich weiß, dass der Standard das Verhalten nicht definiert, wenn eine reine virtuelle Funktion aus einem Konstruktor oder Destruktor aufgerufen wird, außerdem ist dies kein praktisches Beispiel dafür, wie ich Code in der Produktion schreiben würde, es handelt sich nur um einen Test, um zu überprüfen, was der Compiler tut.
Bei der Prüfung desselben Konstrukts in Java wird Folgendes ausgegeben
doSomething( 0 )
Das ergibt Sinn, da param
zum Zeitpunkt des Aufrufs von doSomething()
aus dem Elternkonstruktor nicht initialisiert ist.
Ich würde ein ähnliches Verhalten in C++ erwarten, mit dem Unterschied, dass param
irgendetwas zum Zeitpunkt des Funktionsaufrufs enthält.
Stattdessen führt das Kompilieren des obigen Codes zu einem Linkerfehler mit (c++ (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3)
, der besagt, dass die Referenz auf Parent::doSomething( )
undefiniert ist.
Also lautet meine Frage: Warum ist dies ein Linkerfehler? Wenn dies ein Fehler ist, würde ich erwarten, dass der Compiler sich beschwert, insbesondere weil eine Implementierung der Funktion vorhanden ist. Jede Information darüber, wie der Linker in diesem Fall arbeitet, oder eine Verweis auf weiterführende Literatur wäre sehr willkommen.
Vielen Dank im Voraus! Ich hoffe, dass diese Frage nicht doppelt gestellt wurde, aber ich konnte keine ähnliche Frage finden.