2013-04-02 16 views

risposta

5
const class_name obj_name{func()}; 

scrivendo quanto sopra, l'autore cerca di seguire sintassi inizializzazione uniforme (introdotto dal C++ 11), in modo da evitare problemi causati da vessare parse e parsing più fastidioso, in cui anche i programmatori esperti vengono intrappolati accidentalmente. Sta cercando di inculcare la migliore pratica nel suo cervello in modo che non venga intrappolato occasionalmente nei problemi di analisi come spiegato di seguito.

Considerate questo,

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

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

Ora si può scrivere questo:

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

che richiama il secondo costruttore, che va bene. Fin qui, tutto bene!

Ma accidentalmente uno anche scrivere questo:

Y y(); 

(erroneamente) pensando che richiama il costruttore di default. Ma il fatto è che non invoca il costruttore predefinito. Dichiara invece una funzione che non accetta argomenti e restituisce Y. Questo è chiamato parsing vexing in C++.

Analogamente, si può scrivere questo (accidentalmente),

Y y(X()); 

pensando che richiama il terzo costruttore di passaggio di un oggetto di tipo X che si crea al volo. Di nuovo, è sbagliato.Dichiara invece una funzione che accetta un puntatore a funzione (di tipo funzione che non richiede nulla e restituisce X) e restituisce Y. Si chiama la maggior parte dei fastidiosi parsing in C++.

sintassi di inizializzazione così uniforme evita tutti questi problemi, è possibile scrivere questo:

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

e seguendo la stessa sintassi,

Y { function_call() }; 

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

Questo è uniforme e certamente migliori pratiche, isn' t?

Spero che questo aiuti.

1

A partire dal C++ 11 la funzione è stata introdotta uniform initialization che fornisce diversi modi per inizializzare tipi.

In questo caso, entrambe le sintassi chiameranno il costruttore di copie class_name(class_name const&) (se ne esiste uno). Quindi non c'è una vera differenza. È solo una questione di preferenza.

E 'da notare che la sintassi {} non sempre si comportano come in questo caso: se c'è un costruttore initialization_list del tipo appropriato, che il costruttore viene utilizzato, altrimenti gli elementi della classe vengono inizializzati con il costruttore appropriato .

Nei casi in cui l'più fastidiosi Parse principio (se si può eventualmente essere interpretato come un prototipo di funzione, allora sarà) scioperi si sono tenuti a utilizzare uno dei due per dire al compilatore che avvenga non un prototipo di funzione:

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