2010-01-11 8 views
16

bool "bar" è di default true, ma dovrebbe essere falso, non può essere inizializzato nel costruttore. c'è un modo per inizialo come falso senza renderlo statico?Perché un valore booleano booleano C++ è true per impostazione predefinita?

versione semplificata del codice:

foo.h

class Foo{ 
public: 
    void Foo(); 
private: 
    bool bar; 
} 

foo.c

Foo::Foo() 
{ 
    if(bar) 
    { 
    doSomethink(); 
    } 
} 
+10

Perché non è possibile inizializzarlo nel costruttore? – Kena

+0

perché il costruttore può essere chiamato più di una volta, non posso cambiare quella routine perché sarebbe privo di una maggiore tranquillità del software :( – Christoferw

+27

Come mai il costruttore sarà mai chiamato più di una volta? – jalf

risposta

63

Infatti, per impostazione predefinita non è inizializzato tutti. Il valore visualizzato è semplicemente alcuni valori di cestino nella memoria che sono stati utilizzati per l'allocazione.

Se si desidera impostare un valore di default, dovrete chiedere per essa nel costruttore:

class Foo{ 
public: 
    Foo() : bar() {} // default bool value == false 
    // OR to be clear: 
    Foo() : bar(false) {} 

    void foo(); 
private: 
    bool bar; 
} 

UPDATE C++ 11:

Se è possibile utilizzare un C++ 11 compilatore, è ora possibile costruire di default al posto (la maggior parte del tempo):

class Foo{ 
public: 
    // The constructor will be generated automatically, except if you need to write it yourself. 
    void foo(); 
private: 
    bool bar = false; // Always false by default at construction, except if you change it manually in a constructor's initializer list. 
} 
+8

e quindi hai quasi il 100% di possibilità che "if (bar)" sia vero. –

+2

alcuni compilatori inizializzeranno la memoria in build di debug su un modello specifico. Se si utilizza uno di questi compilatori, le build di debug avranno il 100% di probabilità che la barra sia vera. –

+1

IIRC Darwin inizializza la memoria a zero per impostazione predefinita, così puoi anche finire con quello che sembra essere un comportamento incoerente attraverso le piattaforme. –

1

C/C++ non inizializzare le variabili per voi tutti. La posizione di memoria che è ora in uso dalla barra ha un valore che è interpretato come "vero". Questo non sarà sempre il caso. È necessario inizializzarlo nel costruttore.

+0

Dipende. Le variabili membro POD non sono inizializzate, ma i membri non POD vengono creati automaticamente. E, naturalmente, le variabili globali/statiche sono inizializzate. – jamesdlin

1

Questo programma ha un comportamento non definito. I tipi intrinseci non hanno costruttori. Potresti fare bool bar = bool(); ma è meglio definire il valore effettivo nella tua classe foo.

0

Prova questo:

class Foo 
{ 
    public: 
    void Foo(); 
    private: 
    bool bar; 
} 

Foo::Foo() : bar(false) 
{ 
    if(bar) 
    { 
    doSomething(); 
    } 
} 
+0

foo() non è Foo() ... – Klaim

+0

Oops, @Klaim mi ha dato un esempio. – Bill

+0

foo() è un refuso, foo() dovrebbe essere Foo() – Christoferw

-1

È possibile inizializzare qualsiasi variabile quando si dichiara.

bool bar = 0; 
+0

mi piace lo stesso, ma ottengo un errore C2864 quindi: solo i membri di dati integrale const statici possono essere inizializzati all'interno di una classe – Christoferw

+1

Questo è vero per le variabili locali, ma non per i membri della classe. – Bill

+2

Ma non prima di C++ 0x ... – Debilski

4

La risposta di Klaim è azzeccata. Per "risolvere" il tuo problema potresti usare un constructor initialization list. Vi consiglio caldamente di leggere quella pagina in quanto potrebbe chiarire alcune query simili che potreste avere in futuro.

0

Poiché si sta utilizzando il valore di bar nel ctor, presumo che si stia tentando di impostarlo prima che l'oggetto venga creato? Penso che volevi renderlo una variabile di classe statica invece di una variabile di istanza.