Recuperar valores de variáveis constantes estáticas em um construtor de uma variável estática
-
27-09-2019 - |
Pergunta
Entendo que o código abaixo resultaria na falha de segmentação porque, no CSTR de A, B :: Símbolo ainda não foi inicializado. Mas por que?
Na realidade, A é um objeto que serve como um mapa que mapeia os símbolos de classes como B para seus respectivos IDs. C mantém este mapa (a) estático-ly, de modo que ele possa fornecer o mapeamento como uma função de classe.
A função principal de A é servir como um mapa para C que se inicializa na inicialização. Como devo fazer isso sem falha de segmentação, desde que ainda possa usar o símbolo B :: ID e B :: no código (não #define pls)?
(PS. Suponha que eu tenha implementado os guardas incluídos)
//A.h
#include "B.h"
class A
{
public:
A()
{
std::cout<<B::ID<<std::endl;
std::cout<<B::SYMBOL<<std::endl;
}
};
//B.h
class B
{
public:
static const int ID;
static const std::string SYMBOL;
}
//B.cpp
#include "B.h"
const int B::ID = 1;
const std::string B::SYMBOL = "B";
//C.h
#include "A.h"
class C
{
public:
static A s_A;
};
//C.cpp
#include "C.h"
A C::s_A;
//main.cpp
#include "C.h"
int main(int c, char** p)
{
}
Solução
Use a inicialização preguiçosa de S_A. Isso pode funcionar:
class C
{
public:
static A& getA() { static A s_A; return s_A; }
};
Ou:
class C
{
public:
static A& getA()
{
if( ps_A == NULL) ps_A = new ps_A;
return *ps_A;
}
private:
static A* ps_A;
};
A* C::ps_A = NULL;
Nenhuma solução é segura no fio.
Outras dicas
De que falha de segmentação você está falando? Seu código simplesmente não vai compilar, porque os membros de B
(e B
em si) não são declarado antes da A::A()
. O compilador simplesmente não saberá o que B
é.
Se você trocar as definições de A
e B
, então o código deve compilar e funcionar bem. Enquanto tudo estiver na mesma unidade de tradução, não deve haver problemas com a ordem de inicialização, assumindo que o definições de membros estáticos de B
preceder o definição do C::s_A
. Objetos definidos na mesma unidade de tradução são inicializados na ordem de sua definição, o que significa que quando A::A()
Começa, membros estáticos de B
já são inicializados. Não há potencial para a falha de segmentação neste caso, conforme apresentado.
Se você está obtendo uma falha de segmentação, deve estar fazendo algo de maneira diferente. A ordem de definição é diferente? Múltiplas unidades de tradução talvez? Publique/descreva o código real.