que - ¿Por qué no se llamó al constructor c++ cuando aparece como la variable miembro estática?
que es un objeto en c++ (4)
Tuve un problema extraño,
declara una variable miembro estática cuyo nombre es clase B en clase A. Y inicializa en el archivo cpp. pero el constructor de la clase B nunca fue llamado. Intento usar algunas pequeñas pruebas, el constructor de prueba podría llamarse normalmente. así que es muy extraño para nuestro sistema de producción.
El código como este, en hpp :
class Test
{
public:
Test()
{
ofstream file("/tmp/wup.txt",ios::app);
file << "wup in test" << endl;
file.close();
}
};
//## An extended personality
class TsdNAExtPersonality : public TsdNAPersonality{
public:
TsdNAExtPersonality(
s_gg62_personRec * gg62Header,
TsdNAFunctionType requiredFunctionType);
private:
static Test test;
public:
TsdNAExtPersonality( string * personalityFile, TsdNAFunctionType requiredFunctionType);
};
Y en otro archivo cpp me inicializo con
Test TsdNAExtPersonality::test;
Lo intenté de varias maneras, pero encontré que todas las formas son inútiles.
- no configuró la variable como variable miembro, sino como variable global ==> tampoco puede mostrar
- cambie la variable miembro como puntero y cambie la forma de inicialización como usando new ==> no
el entorno es HP-UX y la compilación es aCC
entonces mi pregunta es:
¿Hay alguna opción de compilación que influya en la variable? en otras palabras, toda la variable estática no se inicializará.
desde el estándar de C ++ debería llamarse cuando la biblioteca estaba cargada, ¿verdad?
Puse otro valor int estático usando la misma manera, podría inicializarse. pero el constructor de la clase no se llama, muy extraño.
¿Hay algún error en mi código?
desde el estándar de C ++ debería llamarse cuando la biblioteca estaba cargada, ¿verdad?
No. La inicialización dinámica de un objeto con una duración de almacenamiento estática se garantiza antes de la ejecución de cualquier función definida en la misma unidad de traducción. Si no existen tales funciones, o su programa nunca las llama, entonces no hay garantía de que alguna vez se inicialicen.
Puse otro valor int estático usando la misma manera, podría inicializarse. pero el constructor de la clase no se llama, muy extraño.
Una variable int
se inicializa estáticamente, antes de que el programa comience, siempre que su inicializador sea constante.
¿Hay alguna opción de compilación que influya en la variable?
No es que yo sepa, pero no estoy familiarizado con su plataforma. Podrías darte más control sobre la creación del objeto al buscar dentro de una función:
static Test & test() {
static Test test;
return test;
}
Ahora está garantizado que se inicializa la primera vez que se llama a la función. Por supuesto, deberá recordar llamarlo en algún momento.
Creo que hay un error en tu compilador.
Ejecutar este código simple en linux / g ++ da los resultados esperados:
#include <iostream>
using namespace std;
class A
{
public:
A() { cout << "Hallo" << endl; }
};
class B
{
public:
static A a;
};
A B::a; // < here the constructor must be called!
int main()
{
cout << "Main runs" << endl;
return 0;
}
Resultados en:
Hallo
Main runs
El constructor DEBE ser llamado cuando se construye el miembro de datos estáticos (línea comentada arriba).
El inicio y el apagado de un programa en C ++ son una especie de áreas grises porque no está claro cuánto de su código ya puede usar (porque se ha inicializado) y cuánto está comenzando. En el momento del cierre, ocurre lo mismo con el destructor ... no está claro cuántos subsistemas ya se han cerrado cuando se destruyen sus instancias estáticas.
Además, nunca se debe usar la inicialización estática para nada que pueda fallar, la depuración antes del inicio o después del final de main
puede ser muy difícil.
Tenga en cuenta también que el orden en el que se inicializan las estáticas no está definido (excepto en relación con otras estáticas en la misma unidad de compilación) y puede cambiar de una compilación a la siguiente. Esto significa que puede vivir feliz con un programa en funcionamiento hasta que, por alguna extraña razón, obtiene un orden de inicialización diferente y las cosas dejan de funcionar sin ningún cambio relevante en el código.
Usar la inicialización estática para cosas extremadamente simples está bien, para todo lo demás no es así y debería hacer una inicialización controlada adecuada.
La inicialización estática en C ++ es:
- Inicialización cero
- Inicialización constante
- Inicialización dinámica
Por lo tanto, su mejor apuesta es la inicialización en la primera llamada de función:
int fn() {
static int result = 42;
return result;
}
EDITAR :
Si quieres inicializar antes de main:
struct Initialize {
Initialize() { fn(); }
}
Initialize initialize;