static
members
Dentro de una definición de clase, la palabra clave static declara miembros que no están vinculados a instancias de clase.
Fuera de la definición de una clase, tiene un significado diferente: consulta storage duration .
ContenidoSintaxisUna declaración para un miembro estático es una declaración de miembro cuyos especificadores de declaración contienen la palabra clave El nombre de cualquier miembro de datos estático y función miembro estática debe ser diferente del nombre de la clase contenedora. ExplicaciónLos miembros estáticos de una clase no están asociados con los objetos de la clase: son variables independientes con duración de almacenamiento o de hilo (desde C++11) storage duration o funciones regulares. La static palabra clave solo se utiliza con la declaración de un miembro estático, dentro de la definición de la clase, pero no con la definición de ese miembro estático: class X { static int n; }; // declaración (usa 'static') int X::n = 1; // definición (no usa 'static') La declaración dentro del cuerpo de la clase no es una definición y puede declarar el miembro como de tipo incompleto (distinto de void ), incluyendo el tipo en el cual el miembro está declarado: struct Foo; struct S { static int a[]; // declaración, tipo incompleto static Foo x; // declaración, tipo incompleto static S s; // declaración, tipo incompleto (dentro de su propia definición) }; int S::a[10]; // definición, tipo completo struct Foo {}; Foo S::x; // definición, tipo completo S S::s; // definición, tipo completo
Para hacer referencia a un miembro estático
struct X { static void f(); // declaración static int n; // declaración }; X g() { return X(); } // alguna función que retorna X void f() { X::f(); // X::f es un nombre calificado de función miembro estática g().f(); // g().f es una expresión de acceso a miembro que referencia a una función miembro estática } int X::n = 7; // definición void X::f() // definición { n = 1; // X::n es accesible simplemente como n en este ámbito } Los miembros estáticos obedecen las reglas de acceso a miembros de clase (private, protected, public) . Funciones miembro estáticasLas funciones miembro estáticas no están asociadas con ningún objeto. Cuando se llaman, no tienen this pointer. Las funciones miembro estáticas no pueden ser virtual , const , volatile , o ref-qualified . La dirección de una función miembro estática puede almacenarse en un pointer to function normal, pero no en un pointer to member function . Miembros de datos estáticosLos miembros de datos estáticos no están asociados con ningún objeto. Existen incluso si no se ha definido ningún objeto de la clase. Solo hay una instancia del miembro de datos estático en todo el programa, con duración de almacenamiento estática, a menos que se utilice la palabra clave thread_local, en cuyo caso hay un objeto por hilo con duración de almacenamiento de hilo(desde C++11). Los miembros de datos estáticos no pueden ser Los miembros de datos estáticos de una clase en el ámbito de un espacio de nombres tienen enlace externo si la clase misma tiene enlace externo (no es miembro de un espacio de nombres anónimo). Las clases locales (clases definidas dentro de funciones) y las clases anónimas, incluidas las clases miembro de clases anónimas, no pueden tener miembros de datos estáticos.
Miembros estáticos constantesSi un miembro de datos estático de tipo integral o de enumeración se declara const (y no volatile ), puede ser inicializado con un inicializador en el que cada expresión sea una expresión constante , directamente dentro de la definición de la clase: struct X { const static int n = 1; const static int m{2}; // desde C++11 const static int k; }; const int X::k = 3;
Si un dato miembro estático const no inline (desde C++17) o un constexpr dato miembro estático (desde C++11) (hasta C++17) es ODR-use , aún se requiere una definición en el ámbito del espacio de nombres, pero no puede tener un inicializador.
struct X { static const int n = 1; static constexpr int m = 4; }; const int *p = &X::n, *q = &X::m; // X::n y X::m son utilizados en ODR const int X::n; // … por lo tanto una definición es necesaria constexpr int X::m; // … (excepto para X::m en C++17) Palabras claveInformes de defectosLos siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.
Referencias
Véase también |