Betrachten Sie diese Datei, first.cpp
, eine Klassendefinition und Verwendung enthalten:Warum erlaubt der ld-Linker mehrere Klassendefinitionen mit denselben Methoden?
#include <iostream>
struct Foo
{
Foo(){ std::cout << "Foo()" << std::endl; }
~Foo(){ std::cout << "~Foo()" << std::endl; }
};
int main(){
Foo f;
return 0;
}
und eine andere, second.cpp
, eine widersprüchliche Klassendefinition enthalten:
#include <iostream>
struct Foo
{
Foo();
~Foo();
};
Foo::~Foo(){ std::cout << "wrong ~Foo()" << std::endl; }
Der Linker über doppelte Symbole beschwert sich, wenn es zwei sind Funktionen mit den gleichen Namen definiert, aber diese Dateien mit doppelten Klassenmethoden kompilieren ohne einen Fehler.
ich mit diesen Befehlen zusammengestellt:
$ g++ -c second.cpp -o second
$ g++ second first.cpp -o first
Neuordnen die Argumente der zweiten g++
Aufruf ändert nicht den Ausgang.
Und wenn first
ausgeführt wird, ist dies die Ausgabe:
$ ./first
Foo()
wrong ~Foo()
Warum der Linker erlauben doppelte Klassenmethoden? Wenn es anscheinend erlaubt ist, warum ist wrong ~Foo()
gedruckt?
Ich denke, es ist an der Version des Compilers hängt, aber es nimmt die ersten gefundenen. – Brady
Es ist GCC 4.6.1. –
Es hat wahrscheinlich etwas mit der Funktion zu tun, die einer Objektdateifunktion Platz macht, wo sie vorhanden ist. Ich nehme an, Sie hätten das gleiche Problem mit dem Konstruktor, wenn Sie eine non-inline-Version in second.cpp deklarierten und das Problem wegfallen würde, wenn beide Quellen die Funktionen inline deklarierten. – forsvarir