2013-09-24 6 views
7

nenne ich Simpletron.cpp haben, die eine leer Datei ist, eine Simpletron.h, die eine Simpletron Klasse deklariert:Keine Implementierung in C++, aber es kann immer noch

class Simpletron 
{  
public: 
    Simpletron(); 
}; 

ich Simpletron() in meinem main.cpp genannt:

#include <iostream> 
#include "Simpletron.h" 

int main(int argc, char *argv[]) 
{ 

    Simpletron s(); 
    std::cin.get(); 
} 

Die Hauptfunktion läuft einfach ohne Warnung oder Fehler. Warum das? Wie kompiliert das überhaupt, wenn es keine Implementierung gibt, mit der die Header-Datei verknüpft werden könnte?

+4

@ Smac89: Nicht, wenn Sie es erklären. Vielleicht werde ich verrückt, aber mindestens 7 andere Menschen haben sich auch geirrt. Dieses Programm sollte einen Linker-Fehler verursachen, [Beispiel] (http://ideone.com/5m0ygK). – GManNickG

+0

@octef: Bitte geben Sie Ihren echten Code und die Befehlszeile an. Zum Beispiel fehlt Ihrer Klassendefinition ein Semikolon nach dem Code. Dies kann nicht der Code sein, den Sie kompilieren. – GManNickG

+0

Sicher, warte mal. – octref

Antwort

24

Diese Zeile:

Simpletron s(); 

ist ein Funktionsprototyp, eine Funktion namens erklärt s, eine Simpletron Rückkehr und ohne Argumente. Es wird keine Simpletron Instanz mit dem Namen s erstellt.

Jetzt könnten Sie fragen, warum sich der Linker nicht über die nicht vorhandene s() Funktion beschweren? Nun, da Sie nur s() deklarieren, aber nie wirklich aufrufen, wird während der Verknüpfung tatsächlich nirgendwo referenziert, so dass Sie keinen Linkfehler erhalten.

13
Simpletron s(); 

Dies ist Funktionsdeklaration, und kein Objektinstanziierung. Die leere Klammer sagt dem Compiler, dass diese Funktion keine Argumente annimmt und ein Objekt vom Typ Simpletron als Wert zurückgibt, so dass keine Konstruktoren aufgerufen werden. Die korrekte Syntax ist, ohne dass die Parameter:

Simpletron s; // You will get an error on this line, as initially expected 

C++ 11 eine syntaktische Funktion hinzufügt, diese Zweideutigkeit vermeidet:

Simpletron s{}; // same as default-initialization 
+0

Wobei "fix" bedeutet, dass ein Link-Zeit Fehler verursacht wird. –

+0

Es wird es nicht beheben. Es wäre ein Fehler. – MahanGM

+4

@MahanGM: "Fix" bedeutet, dass der Code sich wie erwartet verhält. –

5
Simpletron s(); 

Dies ist ein klassischer Fall von "ärgerlichen Parse"; Für den Compiler erstellen Sie keine Variable s vom Typ Simpletron, aber Sie deklarieren eine Funktion mit dem Namen s, nehmen keine Parameter und geben ein Simpletron Objekt zurück.

Dies kommt von der Tatsache, dass dieser Ausdruck sowohl als eine Funktionsdeklaration als auch als eine Variablendeklaration interpretiert werden konnte; Da es eine einfache Alternative gibt, um die Variable zu deklarieren (nämlich einfach die Klammern wegzulassen), müssen die Standardmandate dies als eine Funktionsdeklaration interpretieren.

Dies geht ohne Probleme die Kompilierung-Phase (der Compiler muss nicht die Definitionen aller Methoden haben, sondern nur die Erklärungen), und wahrscheinlich der Linker gibt keinen Fehler, da keine Instanz von Simpletron ist tatsächlich erstellt, so dass es nie wirklich nach der Konstruktordefinition suchen muss (obwohl ich nicht denke, dass es garantiert ist, keine Fehler zu geben, sollte ein besonders gründliches Compiler/Linker-Paar Ihnen einen Fehler für den fehlenden Konstruktor geben können sowieso).

Verwandte Themen