Recuperar valores de variáveis ​​constantes estáticas em um construtor de uma variável estática

StackOverflow https://stackoverflow.com/questions/2640542

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)
    {
    }
Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top