2012-12-18 5 views
6

Ich habe noch nie zuvor in C++, aber es ist seltsam, dass es noch kompiliert, aber nicht das tut, was ich erwartet hatte. Kann mir jemand sagen, was es macht? Bitte beachten Sie den Code, weitere Informationen folgen.Instantiieren einer Klasse in C++: Seltsame Syntax Bug

#include <iostream> 
using namespace std; 

class Test{ 
    public: 
     Test(); 
}; 

Test::Test(){ cout << "ctor" << endl; } 

int main(void){ 

    Test t(); // this compiles but doesn't call the constructor 

    return(0); 
} 

Es wird kompilieren, aber wenn ich versuche, "t" zu verwenden, wird es nicht. Ich war nur von der Konstruktorfunktionalität abhängig und mein Code funktionierte nicht wie erwartet. Die Lösung besteht darin, die Klammer "Test t()" zu verlieren. zu "Test t;". Meine Frage ist, was im "Test t()" vor sich geht; Beispiel, und was denkt der Compiler, dass er es kompilieren lässt.

+5

Suchen drängendsten Parse. – chris

+1

Willkommen zu Ihrem Ritus der Passage. –

+0

Die Frage ist ... wusste der Compiler, was Sie erwartet haben? :) – Carl

Antwort

5

Dies ist die Most Vexing Parse. Nach den C++ - Parsing-Regeln haben Sie im Grunde genommen kein Objekt vom Typ Test mit dem Namen t, sondern eine Funktionsdeklaration für eine Funktion t, die null Argumente akzeptiert und eine Test zurückgibt.

Übrigens erkennt clang ++ diese Situation und gibt eine Warnung aus, die besagt, dass dies wahrscheinlich nicht das tut, was Sie wollen.

+0

Können wir Funktionen in anderen Funktionen deklarieren/definieren? Ich habe nicht angenommen? –

+0

@KarthikT: Ich glaube nicht, dass Sie verschachtelte Funktionen in C++ definieren können, aber Sie können sie sicher deklarieren. Zum Beispiel funktioniert das gut: 'int main() {void foo(); foo(); } void foo() {std :: cout << "foo" << std :: endl; } ' –

+0

@Karthik: Funktionen können in anderen Funktionen * deklariert * werden. Dies ist der Fall seit C. – AnT

1

Dies ist ein häufiges Problem, das treffend als am meisten ärgerlichen Parse genannt wird. Ihre Zeile Test t(); kann auf zwei Arten interpretiert werden.

  1. Es kann eine variable t angeben, die vom Typ ist Test
  2. Es kann eine Funktion t() erklären, die einen Test Wert zurückgibt und keine Argumente

Die C++ Standard Leider erfordert der Compiler Betrachten Sie die zweite Alternative, die ziemlich ärgerlich ist.

Der einfachste Weg, um fix das Parsen ist der Klammer, um loszuwerden, und einfach Ihre Variable als solche deklarieren:

Test t; // Will call the default constructor