2009-09-14 10 views
55

Immaginate di avere una classe C++ Foo e una classe Bar che deve essere creata con un costruttore in cui viene passato un puntatore Foo e questo puntatore è destinato a rimanere immutabile nel ciclo di vita dell'istanza Bar. Qual è il modo corretto di farlo?Come inizializzare un campo const nel costruttore?

In realtà, ho pensato che avrei potuto scrivere come il codice qui sotto, ma non viene compilato correttamente ..

class Foo; 

class Bar { 
public: 
    Foo * const foo; 
    Bar(Foo* foo) { 
     this->foo = foo; 
    } 
}; 

class Foo { 
public: 
    int a; 
}; 

Ogni suggerimento è benvenuto.

risposta

64

Hai bisogno di fare in una lista di inizializzazione:

Bar(Foo* _foo) : foo(_foo) { 
} 

(Si noti che ho rinominato la variabile in entrata per evitare confusione.)

+3

+1, anche se recentemente ho imparato qui che le variabili iniziando con underscore ora * ufficialmente * riservato ;-) –

+1

Solo se sono seguiti da una lettera maiuscola. – GManNickG

+1

o si trovano nello spazio dei nomi! O sono seguiti da un altro trattino basso. Quindi sì, è tecnicamente legale in questo caso, ma direi che è più facile fingere di essere riservati e non usarli affatto. :) – jalf

2

utilizzare un riferimento:

Foo& foo; 
Bar(Foo& f) : foo(f) { } 

È può quindi fare riferimento a foo facilmente in Bar:

foo.doSomething(); 
+1

Io voto come "negativo" perché se fosse l'unica risposta, avrei potuto erroneamente pensare che usare un riferimento fosse l'unico modo per ottenerlo, mentre invece, come mostra l'altra risposta, il trucco è l'elenco di inizializzazione. – puccio

+0

IMHO, i riferimenti sono molto più eleganti in questo caso perché il puntatore non deve essere cambiato affatto dopo essere inizializzato :) – AraK

+1

Ma la domanda era come inizializzare il puntatore. –

0

prova: Bar(Foo* xfoo) : foo(xfoo) {}

12

inizializzazione membri const e altri casi particolari (a tali classi genitore) può essere realizzato nella lista di inizializzazione

class Foo { 
private: 
    const int data; 
public: 
    Foo(int x) : data(x) {} 
}; 

Oppure, allo stesso modo, per l'inizializzazione genitore

class Foo { 
private: 
    int data; 
public: 
    Foo(int x) : data(x) {} 
}; 

class Bar : Foo { 
public: 
    Bar(int x) : Foo(x) {} 
}; 
5

È necessario inizializzare foo nell'elenco di inizializzazione.

class Bar { 
    Foo* const foo; 
    public: 
    Bar(Foo* f) : foo(f) {...} 
}; 
16

Credo che lo si debba fare in un inizializzatore. Per esempio:

Bar(Foo* foo) : foo(foo) { 
} 

Come nota a margine, se non si sarà mai cambiare quello che punti a foo, passarlo in come riferimento:

Foo& foo; 

Bar(Foo& foo) : foo(foo) { 
} 
+2

+1: usa i riferimenti dove vuoi, i puntatori di cui hai bisogno. –