2010-03-19 13 views
11

Sono sempre stato un bravo ragazzo quando si scrive le mie classi, anteponendo tutte le variabili membro con m_:C++ Constructor lista di inizializzazione stranezza

class Test { 
    int m_int1; 
    int m_int2; 
public: 
    Test(int int1, int int2) : m_int1(int1), m_int2(int2) {} 
}; 

int main() { 
    Test t(10, 20); // Just an example 
} 

Tuttavia, di recente ho dimenticato di farlo e ha finito per la scrittura:

class Test { 
    int int1; 
    int int2; 
public: 
    // Very questionable, but of course I meant to assign ::int1 to this->int1! 
    Test(int int1, int int2) : int1(int1), int2(int2) {} 
}; 

ci crediate o no, il codice compilato senza errori/avvertenze e le assegnazioni si è svolta in modo corretto! Solo quando ho fatto il controllo finale prima di controllare il mio codice quando ho capito cosa avevo fatto.

La mia domanda è: perché il mio codice compilato? È qualcosa di simile permesso nello standard C++, o è semplicemente il caso che il compilatore sia intelligente? Nel caso ti stavi chiedendo, stavo usando Visual Studio 2008

+4

Mangling i tuoi nomi è difficilmente quello che considererei un "bravo ragazzo". Come hai scoperto, di solito non è necessario, e nelle rare occasioni in cui lo è, abbiamo il prefisso 'this->'. – jalf

+0

Forse una vittima, vedi http://stackoverflow.com/questions/2227244/what-if-a-constructor-parameter-has-the-same-name-as-a-member-variable-in-c – Abhay

+2

@jalf : D'altra parte una qualche specie di indicatore membro-variabile può a volte rendere più facile la lettura del codice (io uso il finale _ quando non rompe la convenzione esistente). –

risposta

26

Sì, è valido. I nomi nell'elenco di inizializzazione dei membri vengono cercati nel contesto della classe del costruttore, quindi int1 trova il nome della variabile membro.

L'espressione di inizializzazione viene cercata nel contesto del costruttore stesso, pertanto int1 trova il parametro che maschera le variabili membro.

+2

Esatto, giusto e conciso. Bravo! +1 –

+0

+1, bravo ragazzo! xD –

0

Immagino che funzioni perché stavi usando int1 nella lista di inizializzazione, e le uniche cose che puoi inizializzare sono variabili membro => era infatti inequivocabile quale variabile era essere inizializzato.

se tutti i compilatori C++ sarebbe questo perdono è un altro discorso!

+0

IIRC g ++ autorizza anche :-). – p4bl0

+11

È standard C++. –

+1

Grazie per la spiegazione. Naturalmente solo le variabili membro possono apparire al di fuori delle parentesi nell'elenco di inizializzazione. Ma ciò che è dentro le parentesi non è perfettamente chiaro. Ad esempio, se abbiamo: Test (int int1): int1 (int1 + 1), int2 (int1) {} ora che cosa significa int1 sulla seconda parentesi?Significa: int1 o significa questo-> int1? – Andy

15

Quello che hai fatto è di serie C++. Solo le variabili membro o le classi base possono essere inizializzate nella lista di inizializzazione, quindi la variabile al di fuori della paratesi non è ambigua. All'interno delle parentesi, si applicano le regole di scoping tipiche ei membri sono oscurati dai nomi dei parametri.

+1

+1 Questa è l'unica risposta che afferma catagoricamente che questo è il C++ standard oltre a dare una spiegazione. –

2

Questo è perfettamente normale comportamento. Come ha giustamente sottolineato l'AAT, non vi è alcuna ambiguità. Le variabili inizializzate dalla lista devono essere membri della classe. Questo è standard e funziona su tutti i compilatori conformi.

L'unica cosa da ricordare quando si utilizza una lista come questa è che una persona che non capisce questo tipo di codice potrebbe dover mantenerla. Non c'è niente di sbagliato nel scrivere un codice di inizializzazione come questo, purché tu sappia cosa stai facendo.

0

Quello che hai fatto è normale. Questo tipo di implementazione ti evita perfino di usare il puntatore "this" (in questo caso).

Problemi correlati