2010-08-21 23 views
22

Sto cercando di definire una variabile statica pubblico come questo:Definire i membri statici in C++

public : 
     static int j=0;  //or any other value too 

sto ottenendo un errore di compilazione su questa stessa linea: ISO C++ vieta di inizializzazione in-class di statica non const membro `j '.

  1. Perché non è consentito in C++?

  2. Perché i membri const possono essere inizializzati?

  3. Significa questo le variabili statiche in C++ non vengono inizializzati con 0 come in C?

Grazie!

risposta

14

(1.) Perché non è consentito in C++?

Da Bjarne Stroustrup's C++ Style and Technique FAQ: A class is typically declared in a header file and a header file is typically included into many translation units. However, to avoid complicated linker rules, C++ requires that every object has a unique definition. That rule would be broken if C++ allowed in-class definition of entities that needed to be stored in memory as objects.

(2.) Perché i membri const autorizzati a essere inizializzato?

variabili statiche [dirkgently said it better]

(3.) significa in C++ non vengono inizializzati con 0 come in C?

Per quanto ne so, fino a quando si dichiara il membro var statico in un cpp sarà pari a zero-inizializzato se non specificato diversamente:

// in some .cpp 
int Test::j; // j = int(); 
+0

Grazie per l'ottima risposta, mi hai impedito di strapparmi l'udito dalla testa! Ho una domanda però, esiste un modo possibile per fornire un puntatore nullo mentre si definiscono i membri di riferimento? –

+1

@TimVisee Non sono sicuro che sia possibile, almeno in un modo non portatile, senza UB, ma si otterrebbe un riferimento non valido. Se vuoi la semantica NULL basta usare un puntatore o forse usare qualcosa come Boost Optional. –

16

È necessario inizializzare la variabile statica in un file .cpp e non nella dichiarazione della classe.

Quando si dichiara una variabile statica nella classe, può utilizzato senza un'istanza di una classe.

//Header file 
class Test 
{ 
    public: 
    static int j; 
}; 

//In cpp file 

//Initialize static variables here. 
int Test::j = 0; 

//Constructor 
Test::Test(void) 
{ 
    //Class initialize code 
} 
17

Perché non è consentito in C++?

Fino a quando non lo si definisce, la variabile non diventa un valore l.

Perché i membri const possono essere inizializzati?

Anche in questo caso, è necessaria una definizione se si desidera prendere l'indirizzo della variabile.

9.4.2 membri dati statici

La dichiarazione di servizi di dati statici membro nella sua definizione classe non è una definizione e può essere di tipo incompleto diverso cv -qualificato qualificata. La definizione per un membro di dati statici deve apparire in un ambito dello spazio dei nomi che racchiude la definizione di classe del membro. Nella definizione a ambito namespace, il nome del membro di dati static deve essere qualificato con il suo nome di classe utilizzando il :: dell'operatore. L'espressione di inizializzazione nella definizione di un dati statici membro è nel campo di applicazione della sua classe

Inoltre, si tratta principalmente di un artefatto utilizzo in modo che si può scrivere:

class S { 
     static const int size = 42; 
     float array[ size ]; 
}; 

fa questo significa che le variabili statiche in C++ non sono inizializzate con 0 come in C?

No essi sono:

3.6.2 Inizializzazione delle variabili non locali

variabili con durata statica stoccaggio (3.7.1) o durata di conservazione filo (3.7. 2) deve essere zeroinitialized (8.5) prima di qualsiasi altra inizializzazione prende il numero .

Anche se le cose si fanno un po 'più complicato in C++ 0x. Tutti i tipi letterali possono ora essere inizializzati (al contrario dei soli tipi interi nello standard corrente), il che significherebbe che tutti i tipi scalari (float inclusi) e alcuni tipi di classi possono ora essere inizializzati usando un inizializzatore nella dichiarazione.

+0

Perché la definizione di un intero const statico non è necessaria se l'indirizzo non viene utilizzato? Esso (static-const-int definito in .h) compila, collega correttamente senza definizione. In tal caso, poiché, quando C++ consente questo tipo di dichiarazione senza definizione, dal C++ 98? da quando C++ 03? Fonti autentiche per favore. C++ Standard (9.4.2) non è sincronizzato con i compilatori. Menziona che il membro deve ancora essere definito se è usato nel programma. Quindi, ti dirò, non sto cercando di citare lo standard C++. Quello che andrà bene è, GCC changelog/C++ Committee Notes. – smRaj

8

La risposta breve:

È equivalente a dire extern int Test_j = 0;.

Se è stato compilato, cosa accadrebbe? Ogni file sorgente incluso il file di intestazione della tua classe definirà un simbolo chiamato Test :: j inizializzato a 0. Il linker tende a non gradirlo.

+4

+1.'extern' getta luce sulla natura del problema qui. – Cheezmeister

2
class GetData   
{  
private:  
static int integer; //Static variable must be defined with the extension of keyword static;  
public:  
static void enter(int x)  
{  
integer = x; //static variable passed through the static function  
} 
static int show() //declared and defined 
{ 
    return integer; //will return the integer's value 
}   
};   
int GetData::integer = 0; //Definition of the static variable  
int main()  
{  
    GetData::enter(234); //value has been passed through the static function enter. Note that class containing static variables may not have the object in main. They can be called by scope resolution operator in main. 
    cout<<GetData::show();  
}  
Problemi correlati