2013-04-02 8 views

Antwort

5
const class_name obj_name{func()}; 

durch die oben schreiben, ist der Autor versucht, einheitliche Initialisierung Syntax (eingeführt von C++ 11) zu folgen, um Probleme, die durch ärgerliche Parse zu vermeiden und am meisten ärger parse, in dem sogar erfahrene Programmierer versehentlich gefangen sind. Er versucht, die beste Praxis in sein Gehirn einzuprägen, damit er nicht wie unten erklärt in die genannten Parsing-Probleme gerät.

das Betrachten

struct X { /*....*/ }; // some class 

struct Y 
{ 
    Y(); 
    Y(int i); 
    Y(X x); 
}; 

Jetzt kann man schreiben:

Y y(100); // declare an object y of type Y 

, der den zweiten Konstruktor aufruft, was in Ordnung ist. So weit, so gut!

Aber accidently man sogar schreiben:

Y y(); 

(fälschlicherweise) denken, dass es den Standard-Konstruktor aufruft. Tatsache ist jedoch, dass der Standardkonstruktor nicht aufgerufen wird. Stattdessen deklariert er eine Funktion y, die kein Argument akzeptiert und Y zurückgibt. Das heißt vexing Parse in C++.

Ebenso kann man diese (versehentliche) schreiben,

Y y(X()); 

denkt, dass es den dritten Konstruktor ruft X ein Objekt vom Typ vorbei, die im laufenden Betrieb erstellt wird. Auch das ist falsch.Stattdessen deklariert er eine Funktion y, die einen Funktionszeiger (vom Typ function, der nichts nimmt und X zurückgibt) und Y zurückgibt. Es heißt am meisten ärgerlichen Parse in C++.

So einheitliche Initialisierung Syntax vermeidet alle diese Fragen, können Sie schreiben:

Y y1{};  // invokes 1st constructor 
Y y2{100}; // invokes 2nd constructor 
Y y3{X{}}; // invokes 3rd constructor 

und im Anschluss an die gleiche Syntax,

Y { function_call() }; 

const class_name obj_name { func() }; // taken from your question! 

Das heißt einheitliche und sicherlich beste Praxis, isn‘ t?

Hoffe, dass hilft.

1

Ab C 11 ++ die uniform initialization Funktion wurde eingeführt, die mehr Möglichkeiten bieten Typen zu initialisieren.

In diesem Fall rufen beide Syntaxen den Kopierkonstruktor class_name(class_name const&) auf (falls einer existiert). Daher gibt es keinen wirklichen Unterschied. Es ist nur eine Frage der Präferenz.

Es zu beachten ist, dass die {} Syntax wie verhalten sich nicht immer in diesem Fall: Wenn es ein initialization_list Konstruktor des entsprechenden Typs ist, wird dieser Konstruktor verwendet, sonst die Klassenelemente werden mit dem entsprechenden Konstruktor initialisiert .

In Fällen, in denen die drängendsten Parse Prinzip (wenn es möglicherweise als Funktionsprototyp interpretiert werden kann, dann wird es sein) strikes Sie verpflichtet sind, entweder eine der beiden zu verwenden, um dem Compiler mitzuteilen, dass die folgende ist kein Funktionsprototyp:

typename class_name obj_name(func()); 
class_name obj_name { func() };