variable una son que publica programacion metodo las globales estaticas estatica declaraciones c++ static

c++ - una - ¿Por qué la variable estática necesita ser definida explícitamente?



variables estaticas c# (5)

En la clase:

class foo { public: static int bar; //declaration of static data member }; int foo::bar = 0; //definition of data member

Tenemos que definir explícitamente la variable estática, de lo contrario resultará en una

undefined reference to ''foo::bar''

Mi pregunta es:

¿Por qué tenemos que dar una definición explícita de una variable estática?

Tenga en cuenta que esto NO es un duplicado de una undefined reference to static variable preguntas de undefined reference to static variable . Esta pregunta pretende preguntar la razón detrás de la definición explícita de una variable estática.


A principios de C ++, se le permitió definir los miembros de datos static dentro de la clase que ciertamente violan la idea de que la clase es solo un plano y no deja de lado la memoria. Esto se ha caído ahora.

Poner la definición de miembro static fuera de la clase enfatiza que la memoria se asigna solo una vez para static miembro de datos static (en tiempo de compilación). Cada objeto de esa clase no tiene copia propia.


Dentro de la clase solo está declarando la variable, es decir: le dice al compilador que hay algo con este nombre. Sin embargo, una variable estática debe obtener algo de espacio de memoria para vivir, y esto debe estar dentro de una unidad de traducción. El compilador reserva este espacio solo cuando DEFINES la variable.


Desde el principio de los tiempos, el lenguaje C ++, al igual que C, se construyó sobre el principio de traducción independiente . Cada unidad de traducción es compilada por el compilador de manera independiente, sin ningún conocimiento de otras unidades de traducción. Todo el programa solo se une más tarde, en la etapa de enlace. La etapa de vinculación es la etapa más temprana en la que el enlazador ve todo el programa (se ve como una colección de archivos de objetos preparados por el compilador ).

Para respaldar este principio de traducción independiente , cada entidad con enlace externo debe definirse en una unidad de traducción y en una sola unidad de traducción. El usuario es responsable de distribuir tales entidades entre diferentes unidades de traducción. Se considera parte de la intención del usuario , es decir, se supone que el usuario debe decidir qué unidad de traducción (y archivo de objeto) contendrá cada definición.

Lo mismo se aplica a los miembros estáticos de la clase. Los miembros estáticos de la clase son entidades con enlace externo. El compilador espera que usted defina esa entidad en alguna unidad de traducción. El propósito de esta función es darle la oportunidad de elegir esa unidad de traducción. El compilador no puede elegirlo por ti. Es, nuevamente, una parte de su intención, algo que tiene que decirle al compilador.

Esto ya no es tan crítico como solía ser hace un tiempo, ya que el lenguaje ahora está diseñado para tratar (y eliminar) una gran cantidad de definiciones idénticas (plantillas, funciones en línea, etc.), pero la Regla de una definición sigue siendo válida. Arraigado en el principio de traducción independiente .

Además de lo anterior, en el lenguaje C ++, el punto en el que define su variable determinará el orden de su inicialización con respecto a otras variables definidas en la misma unidad de traducción. Esto también forma parte de la intención del usuario , es decir, algo que el compilador no puede decidir sin su ayuda.


La estructura no es variable, pero su instancia es. Por lo tanto, podemos incluir la misma declaración de estructura en varios módulos, pero no podemos tener el mismo nombre de instancia definido globalmente en múltiples módulos .

La variable estática de la estructura es esencialmente una variable global. Si lo definimos en la declaración de estructura, no podremos utilizar la declaración de estructura en varios módulos. Porque eso daría lugar a que se definiera el mismo nombre de instancia global (de variable estática) en varios módulos, lo que provocaría un error de vinculador "Múltiples definiciones del mismo símbolo"


static es un tipo de almacenamiento, cuando declara la variable que le está diciendo al compilador "esta semana esté en algún lugar de la sección de datos" y cuando la use posteriormente, el compilador emite código que carga un valor desde una dirección TBD.

En algunos contextos, el compilador puede controlar que una estática sea realmente una constante de tiempo de compilación y reemplazarla con tal, por ejemplo

static const int meaning = 42;

Dentro de una función que nunca toma la dirección del valor.

Sin embargo, cuando se trata de miembros de la clase, el compilador no puede adivinar dónde se debe crear este valor. Puede estar en una biblioteca con la que se vinculará, o en una dll, o podría estar proporcionando una biblioteca en la que el consumidor de la biblioteca debe proporcionar el valor.

Generalmente, cuando alguien pregunta esto, sin embargo, es porque están haciendo mal uso de miembros estáticos.

Si todo lo que quiere es un valor constante, por ejemplo.

static int MaxEntries; ... int Foo::MaxEntries = 10;

Estaría mejor con uno u otro de los siguientes

static const int MaxEntries = 10; // or enum { MaxEntries = 10 };

La estática no requiere una definición por separado hasta que algo intente tomar la dirección o formar una referencia a la variable, la versión enum nunca lo hace.