Para entender esto, usted debe tener una buena comprensión de compiling and linking, y las diferencias entre declarations and definitions.
Considérese la clase siguiente:
//In header file
class Example {
static bool exampleStaticMember;
};
Aquí, exampleStaticMember
se declara pero no se define. Esto significa que si exampleStaticMember
se utiliza de una manera que significa que debe tener una dirección, entonces debe haber una definición separada para ella. En general, ninguna declaración de un miembro de datos estáticos en una definición de clase es una definición de ese miembro.
La declaración requerida generalmente se coloca en el archivo cpp que contiene las otras definiciones para los miembros de la clase. Debe estar en el mismo espacio de nombres que la definición de clase. La definición se ve típicamente como:
//In source file:
//This may optionally have an initialiser (eg "= true")
bool Example::exampleStaticMember;
la definición se puede poner en cualquier archivo cpp, pero no debe ser puesto en la cabecera de la clase, porque eso sería probable que se rompa el One Definition Rule.
Como caso especial, si la variable miembro estática es un tipo integral o de enumeración const entonces puede tener un inicializador en la definición de clase:
//In header file
class Example {
static const int initialised = 15;
};
En este caso, la definición en el archivo CPP es siendo necesaria, pero no se le permite tener un inicializador: miembros
//In source file
//Note: no initialiser!
const int Example::initialised;
estáticas que han sido inicializados como esto se pueden utilizar en expresiones constantes.
plantillas
Para un miembro de datos estáticos de una plantilla, las cosas son un poco diferentes. El miembro estático se debe definir en la cabecera junto con el resto de la clase:
//In header file
template<typename T>
class Example {
static int exampleInt;
static T exampleT;
}
template<typename T> int Example<T>::exampleInt;
template<typename T> T Example<T>::exampleT;
Esto funciona porque hay una excepción específica a la Regla de una definición de los miembros de datos estáticos de plantillas de clase.
Otros usos de estática
cuando se aplica la palabra clave static
a las funciones y objetos que no están en un ámbito de clase puede tener un significado muy diferente.
Cuando se aplica a objetos en un alcance de función, declara un objeto que se inicializa en la primera ejecución de la función y que posteriormente conserva su valor entre llamadas de función.
Cuando se aplica a objetos o funciones en el ámbito del espacio de nombres (fuera de cualquier definición de clase o función), declara objetos o funciones con internal linkage. Este uso está en desuso para los objetos, ya que el unnamed-namespace proporciona una mejor alternativa.
http://www.parashift.com/c++faq-lite/ctors.html#faq-10.12 – PlasmaHH