2010-08-21 22 views
22

que estoy tratando de definir una variable estática pública como esto:Definición de los miembros estáticos en C++

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

estoy recibiendo un error de compilación en esta misma línea: ISO C++ prohíbe la inicialización en su clase de estática no constante miembro `j '.

  1. ¿Por qué no está permitido en C++?

  2. ¿Por qué se pueden inicializar los miembros de const?

  3. ¿Esto significa que las variables estáticas en C++ no se inicializan con 0 como en C?

Gracias!

Respuesta

14

(1.) ¿Por qué no está permitido en C++?

De 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.) ¿Por qué los miembros const permite ser inicializado?

[dirkgently said it better]

(3.) ¿Quiere decir esto variables estáticas en C++ no se inicializan con 0 como en C?

Por lo que yo sé, siempre y cuando se declara el miembro estático var en un .cpp será cero inicializan si no se especifica lo contrario:

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

Gracias por la gran respuesta, ¡me impidió sacar mi oído de mi cabeza! Tengo una pregunta, ¿hay alguna manera de proporcionar un puntero nulo mientras se definen los miembros de referencia? –

+1

@TimVisee No estoy seguro de si es posible, al menos de forma portátil, no UB, pero terminaría con una referencia no válida. Si quieres semántica NULL simplemente usa un puntero o tal vez uses algo como Boost Opcional. –

16

Tendrá que inicializar la variable estática en un archivo .cpp y no en la declaración de clase.

Cuando declara una variable estática en la clase, puede utilizarse sin crear una instancia de una clase.

//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

¿Por qué no permitido en C++?

Hasta y a menos que lo defina, la variable no se convierte en un valor l.

¿Por qué se pueden inicializar los miembros de const?

Incluso en este caso, se requiere una definición si se va a tomar la dirección de la variable.

9.4.2 miembros de datos estáticos

la declaración de un miembro de datos estáticos en su definición de clase no es una definición y puede ser de un tipo incompleto distinto cv - vacío calificado. La definición de un miembro de datos estáticos debe aparecer en un ámbito de espacio de nombres que incluye la definición de clase del miembro. En la definición en ámbito de espacio de nombres, el nombre del miembro de datos estáticos se debe calificar por su nombre de clase utilizando el operador :: . La expresión de inicialización en la definición de un conjunto de datos estáticos miembro está en el alcance de su clase

Además, se trata fundamentalmente de un artefacto de uso por lo que se puede escribir:

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

¿El estas variables estáticas medias en C++ no se inicializan con 0 como en C?

No son:

3.6.2 Inicialización de variables no locales

variables con duración estática de almacenamiento (3.7.1) o de la duración de almacenamiento de hilo (3.7. 2) se debe ceroinicializar (8.5) antes de que cualquier otra inicialización tome el lugar .

Aunque las cosas se vuelven un poco más complicadas en C++ 0x. Ahora se pueden inicializar todos los tipos literales (a diferencia de solo los tipos integrales en el estándar actual) lo que significa que todos los tipos escalares (flotantes incluidos) y algunos tipos de clase ahora se pueden inicializar usando un inicializador en la declaración.

+0

¿Por qué no se requiere la definición de static const integer si la dirección no está tomada? It (static-const-int definido en .h) compila, enlaces exitosamente sin definición. Si es así, ¿desde cuándo C++ permite este tipo de declaración sin definición, ya que C++ 98? desde C++ 03? Fuentes auténticas por favor. C++ Standard (9.4.2) no está sincronizado con los compiladores. Menciona que el miembro aún se definirá si se usa en el programa. Entonces, les diré, no estoy buscando citas del Estándar C++. Lo que será bueno es GCC changelog/C++ Committee Notes. – smRaj

8

La respuesta corta:

Es equivalente a decir extern int Test_j = 0;.

Si compiló, ¿qué pasaría? Cada archivo fuente, incluido el archivo de encabezado de su clase, definiría un símbolo llamado Test :: j inicializado a 0. El enlazador tiende a no gustarle.

+4

+1."extern" arroja luz sobre la naturaleza del problema aquí. – 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();  
}  
Cuestiones relacionadas