¿Cómo acceder a miembros estáticos de una clase?

4 minutos de lectura

avatar de usuario
sorush-r

Estoy empezando a aprender C++ y Qt, pero a veces el código más simple que pego de un libro da como resultado errores.

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 trato de 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 lo mismo que lo declarado. aquí y aquí (¿no es así?). Entonces, ¿qué tiene de malo el código anterior?

avatar de usuario
flexografía

Ha declarado que los miembros estáticos están bien, pero no definido ellos en cualquier lugar.

Básicamente, lo que ha dicho “existe algún miembro estático”, pero nunca reserve algo de memoria para ello, necesita:

int A::x = 100;

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

  • ¿No es esto una declaración: static int getX(){return x;}?

    – sorush-r

    5 de noviembre de 2010 a las 9:11

  • En ese contexto, está declarando y definiendo getX() al mismo tiempo. Sin {return x;} sería solo una declaración. La definición es “el bit que hace que funcione”, que es una implementación o algún almacenamiento real.

    – Flexografía

    5 de noviembre de 2010 a las 9:12


Sección [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 que no sea un vacío calificado con cv. La definición de un miembro de datos estáticos aparecerá en un ámbito de espacio de nombres que incluya la definición de clase del miembro.. En la definición en el ámbito del espacio de nombres, el nombre del miembro de datos estáticos se calificará por su nombre de clase utilizando el :: operador

Debe definir la variable de miembro estático de la clase fuera de la clase, ya que las variables de miembro estático requieren declaración y definición.

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

int A::x;         // STATIC MEMBER VARIABLE x DEFINITION

int main()
{
   A::x = 100;    // REMOVE int FROM HERE
   cout<<A::getX();
   return 0;
}

  • por qué necesitamos int A::x; c++ es MUY feo

    – canbax

    8 ago. 2019 a las 10:30

avatar de usuario
martín york

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;
   // Notice no 'int' keyword before A::x on this line. You can modify A::x

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

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

avatar de usuario
cullub

Prueba 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;
}

avatar de usuario
thkala

Ahora que ha averiguado cómo usar miembros de clase estáticos, le aconsejaré que, por lo general, solo los use en las siguientes circunstancias:

  • Para uso en plantillas. Entonces, en su ejemplo, podría tener GetX() en diferentes clases y en una plantilla en algún lugar que usaría

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

    aunque evidentemente 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 es el caso de las devoluciones de llamadas.

El resto del tiempo, probablemente pueda usar funciones y variables de nivel de unidad de compilación, lo que tiene la ventaja de sacar a sus miembros del encabezado (particularmente si son privados). Cuantos menos detalles de implementación proporcione, mejor.

¿Ha sido útil esta solución?