2010-11-05 15 views
19

Estoy empezando a aprender C++ y Qt, pero a veces el código más simple que pego de un libro produce errores.¿Cómo acceder a los miembros estáticos de una clase?

Estoy usando g++4.4.2 en Ubuntu 10.04 con QtCreator IDE. ¿Hay alguna diferencia entre la sintaxis del compilador g ++ y otros compiladores? Por ejemplo, cuando intento acceder a miembros estáticos, algo siempre sale mal.

#include <iostream> 
using namespace std; 
class A 
{ 
    public: 
     static int x; 
     static int getX() {return x;} 
}; 
int main() 
{ 
    int A::x = 100; // error: invalid use of qualified-name 'A::x' 
    cout<<A::getX(); // error: : undefined reference to 'A::x' 
    return 0; 
} 

creo que es exactamente el mismo que declaró here y here (¿no?). Entonces, ¿qué pasa con el código anterior?

Respuesta

30

Ha declarado bien los miembros estáticos, pero no defined en ninguna parte.

Básicamente lo que has dicho "existe algún miembro estático", pero nunca dejar de lado algo de memoria para ello, se necesita:

int A::x = 100; 

En algún lugar fuera de la clase y no interior principal.

+1

No es ésta una declaración: static int getX() {return x;}? –

+0

En ese contexto, declara y define getX() al mismo tiempo. Sin {return x;} sería solo una declaración. La definición es "el bit que lo hace funcionar", que es una implementación o algún almacenamiento real. – Flexo

2

La definición de las variables miembro estáticas tienen que vivir en el ámbito de archivo, es decir, fuera de todas las funciones, etc.

6

Probar:

#include <iostream> 
using namespace std; 
class A 
{ 
    public: 
     // This declares it. 
     static int x; 
     static int getX(){return x;} 
}; 

// Now you need an create the object so 
// This must be done in once source file (at file scope level) 
int A::x = 100; 


int main() 
{ 
    A::x = 200; 
    // Note no int here. You can modify it 

    cout<<A::getX(); // Should work 
    return 0; 
} 
+0

Ok. funciona. pero para las clases de plantilla, da este error: muy pocas listas de parámetros de plantilla. (Escribo int SP :: free = 100;) –

+1

@Sorush Rabiee: Lo siento, no soy vidente. Deberá mostrar algún código que demuestre el problema. –

7

Sección [9.4.2]

miembros de datos estáticos

The declaration of a static data member in its class definition is not a definition and may be of an incomplete type other than cv-qualified void. The definition for a static data member shall appear in a namespace scope enclosing the member’s class definition. In the definition at namespace scope, the name of the static data member shall be qualified by its class name using the :: operator

1

Ahora ha trabajado la manera de utilizar miembros de la clase estática voy a aconsejarle que se debe utilizar por lo general ellos sólo en las siguientes circunstancias:

  • Para su uso en las plantillas. Así que en su ejemplo, usted puede GetX() en diferentes clases y en una plantilla de sitio en el que utilizar

    template< typename T > 
    int func() 
    { 
        return T::GetX(); 
    } 
    

    aunque obviamente más elaborado. Pero aquí su función estática en una clase tiene un propósito.

  • Donde la función necesita acceso a la clase, es decir, a miembros privados. Podrías convertirlo en un amigo, pero también puedes hacerlo estático. A menudo el caso en las devoluciones de llamada.

El resto del tiempo es probable que pueda utilizar las funciones de nivel de compilación de unidades y variables que tiene la ventaja de tomar sus miembros fuera de la cabecera (particularmente si son privados). Cuanto menos detalle de implementación dé, mejor.

2

probar este ejemplo:

#include<iostream> 
using namespace std; 

class check 
{ 
     static int a; 
    public: 
     void change(); 
} ; 
int check::a=10; 
void check::change() 
{ 
    a++; 
    cout<<a<<"\n"; 
} 

int main() 
{ 

    int i,j; 
    check c; 
    check b; 
    c.change(); 
    b.change(); 
    return 0; 
} 
+1

¿Por qué no podemos simplemente escribir check :: a = 10; (sin el especificador "int")? Quiero decir, check :: a ya fue declarado como int –

+0

La sintaxis para definir una variable estática no const fuera de la clase es "Return_type class_name :: static_variable = Initialization". si omitimos el tipo de devolución, el compilador arroja un error de sintaxis. Lo mismo es aplicable para definir una función miembro fuera de la clase –

0

Caso 1: variable estática

Como todos sabemos, la definición de una variable estática dentro de una clase que tirar error de compilación. P.ej.a continuación

class Stats 
{ 
    public: 
    static int AtkStats[3]; 
    *static int a =20;*  // Error: defining a value for static variable 
}; 

int Stats::AtkStats[3] = {10, 0, 0}; 

Salida:

error: ISO C++ forbids in-class initialization of non-const static member 'Stats::a' 

Caso 2: const variable estática

Para const variable estática, podemos definir un valor, ya sea dentro de una clase o de clase exterior.

class Stats 
{ 
    public: 
    static const int AtkStats[3]; 
    static const int a =20;  // Success: defining a value for a const static 
}; 

const int Stats::AtkStats[3] = {10, 0, 0}; 

const int Stats::a = 20;  // we can define outside also 

Salida:

Compilation success. 
Cuestiones relacionadas