2010-08-20 27 views
45

E 'possibile inizializzare un valore const statico al di fuori del costruttore? Può essere inizializzato nello stesso luogo in cui vengono trovate le dichiarazioni dei membri?Come inizializzare un membro const const in C++?

class A { 
private: 
    static const int a = 4; 
    /*...*/ 
}; 
+8

Sì, ciò che funziona (ma solo per i tipi interi). – UncleBens

+3

Volevo solo aggiungere che 'static' non ha nulla a che fare con i costruttori dato che i membri' static' non sono specifici per una data istanza ed esistono al di fuori di essa. – ereOn

+0

Infatti, * devi * inizializzare le statistiche const all'esterno di un costruttore di classi. Altrimenti non sarebbe statico. Ducy? –

risposta

54

Sì, è possibile, ma solo per i tipi int. Se vuoi che il tuo membro statico sia di un altro tipo, dovrai definirlo da qualche parte in un file cpp.

class A{ 
private: 
static const int a = 4; // valid 
static const std::string t ; // can't be initialized here 
... 
... 
}; 


// in a cpp file where the static variable will exist 
const std::string A::t = "this way it works"; 

Inoltre, notare che questa regola sono stati rimossi in C++ 11, ora (con un compilatore che fornisce la funzione) è possibile inizializzare ciò che si desidera direttamente nella dichiarazione di membro della classe.

+0

perché const stat double = value; non funziona? – anarhikos

+2

@anarhikos - l'inizializzazione in classe funziona solo per i tipi interi. 'double' non è un tipo integrale. –

+1

@anrhikos: Ecco perché non dovresti definire all'interno della classe. Si dovrebbe definire al di fuori della classe come una questione di pratica (vedi la mia risposta) –

27

Static data members (C++ only)

La dichiarazione di un membro di dati statici nell'elenco dei membri di una classe non è una definizione. È necessario definire il membro statico al di fuori della dichiarazione della classe, nell'ambito dello spazio dei nomi. Per esempio:

class X 
{ 
public: 
     static int i; 
}; 
int X::i = 0; // definition outside class declaration 

Dopo aver definito un membro di dati statici, esiste anche se non esistono oggetti della classe del membro di dati statici. Nell'esempio precedente, non esistono oggetti di classe X anche se il membro dati statici X :: i è stato definito.

I membri di dati statici di una classe nello scope dello spazio dei nomi hanno un collegamento esterno. L'inizializzatore per un membro dati statici è nell'ambito della classe che dichiara il membro.

Un membro di dati statici può essere di qualsiasi tipo tranne che per vuoto o vuoto qualificato con const o volatile. Non è possibile dichiarare un membro di dati statici come modificabile.

È possibile avere una sola definizione di un membro statico in un programma. Classi senza nome, classi contenute in classi senza nome e classi locali non possono avere membri di dati statici.

I membri di dati statici e i relativi inizializzatori possono accedere ad altri membri statici privati ​​e protetti della loro classe. Il seguente esempio mostra come inizializzare membri statici utilizzando altri membri statici, anche se questi membri sono privati:

class C { 
     static int i; 
     static int j; 
     static int k; 
     static int l; 
     static int m; 
     static int n; 
     static int p; 
     static int q; 
     static int r; 
     static int s; 
     static int f() { return 0; } 
     int a; 
public: 
     C() { a = 0; } 
     }; 

C c; 
int C::i = C::f(); // initialize with static member function 
int C::j = C::i;  // initialize with another static data member 
int C::k = c.f();  // initialize with member function from an object 
int C::l = c.j;  // initialize with data member from an object 
int C::s = c.a;  // initialize with nonstatic data member 
int C::r = 1;   // initialize with a constant value 

class Y : private C {} y; 

int C::m = Y::f(); 
int C::n = Y::r; 
int C::p = y.r;  // error 
int C::q = y.f();  // error 

Le initializations C :: p e C :: causare errori q perché y è un oggetto di una classe derivata privatamente da C e i suoi membri non sono accessibili ai membri di C.

Se un membro di dati statici è di tipo const integrale o const enumeration, è possibile specificare un inizializzatore costante nella dichiarazione del membro di dati statici. Questo inizializzatore costante deve essere un'espressione costante integrale. Si noti che l'inizializzatore costante non è una definizione. È ancora necessario definire il membro statico in uno spazio dei nomi che racchiude. Il seguente esempio illustra ciò:

#include <iostream> 
using namespace std; 

struct X { 
    static const int a = 76; 
}; 

const int X::a; 

int main() { 
    cout << X::a << endl; 
} 

I gettoni = 76 alla fine della dichiarazione di statica membro di dati a è una costante inizializzatore.

0

Se ricordo correttamente, non è possibile definirlo all'interno della classe. È esplicitamente necessario definirlo all'esterno come menzionato da pablo.

3

Non è possibile inizializzare i membri statici all'interno dei costruttori. Tipi integrali che è possibile inizializzare in linea alla loro dichiarazione. Altri membri statici devono essere definiti (in un .cpp) File:

// .h 
class A{ 
private: 
static const int a = 4; 
static const foo bar; 
... 
... 
}; 

// .cpp 
const foo A::bar = ...; 
10

Solo per motivi di completezza, sto aggiungendo le variabili membro del modello statico.

template<class T> struct X{ 
    static T x; 
}; 

template<class T> T X<T>::x = T(); 

int main(){ 
    X<int> x; 
} 
Problemi correlati