class X
{
public:
int normalValue = 5;
static const int i = 0; // declaration, with initializer
};
const int X::i; // definition
es decir, ¿Qué debe estar fuera de la clase es una definición, no la inicialización.
Esto se debe a una variable debe tener una dirección en la memoria (a menos que sólo se usa en situaciones limitadas, como en expresiones constantes de tiempo de compilación.)
Existe una variable miembro no estática dentro del objeto que es una miembro de, por lo que su dirección depende de la dirección del objeto que lo contiene. Cada vez que crea un nuevo X
, también crea una nueva variable X::normalValue
. La vida útil del miembro de datos no estáticos comienza con el constructor de la clase. La sintaxis de NSDMI no tiene nada que ver con la dirección de la variable en la memoria, solo le permite proporcionar un valor inicial en un lugar, en lugar de repetirlo en cada constructor con una lista de inicializadores de constructor explícita.
Por otro lado, una variable miembro estática no está contenida dentro de una instancia de la clase, existe independientemente de cualquier instancia única y existe desde el inicio del programa, en una dirección fija. Para que una variable miembro estática (o cualquier otro objeto global) obtenga una dirección única, el vinculador debe ver exactamente una definición de la variable estática, en exactamente un archivo de objeto, y asignarle una dirección.
Dado que una variable estática necesita exactamente una definición en exactamente un archivo de objeto, no tiene sentido permitir esa definición en la clase, dado que las definiciones de clase suelen existir en archivos de encabezado y se incluyen en varios archivos de objeto . Entonces, aunque puede proporcionar un inicializador en la clase, aún necesita definir el miembro de datos estáticos en alguna parte.
También puede mire como declarar una variable extern
:
namespace X {
extern int i;
}
Esto declara la variable, pero debe haber una definición en algún lugar en el programa:
int X::i = 0;
Because. ;) Así es como se define el idioma. ;) – jalf
Tiene permitido 'static const int i = 10'. –
@CharlesBeattie, eso todavía no es una definición, y algunas veces se necesita una definición, vea http://gcc.gnu.org/wiki/VerboseDiagnostics#missing_static_const_definition –