Récupération des valeurs des variables const statiques à un constructeur d'une variable statique

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

Question

Je comprends que le code ci-dessous entraînerait une erreur de segmentation car au CSTR A, B :: SYMBOLE n'a pas été initialisé encore. Mais pourquoi?

En réalité, A est un objet qui sert de carte qui associe les SYMBOLES des classes comme B à leurs ID respectifs. C est titulaire de cette carte (A) statique-ly telle sorte qu'il peut fournir à la cartographie en fonction de la classe.

La fonction principale de A est de servir comme une carte C qui elle-même initialise au démarrage. Comment dois-je être en mesure de le faire sans erreur de segmentation, à condition que je ne peux toujours utiliser B :: ID :: et B SYMBOLE dans le code (pas #define pls)?

(ps. Supposons que je l'ai mis en œuvre les gardes comprennent)

//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)
    {
    }
Était-ce utile?

La solution

Utilisation de l'initialisation tardive S_A. Ce travail de puissance:

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;

Ni solution est thread-safe.

Autres conseils

Quelle erreur de segmentation Vous parlez de? simplement votre code ne compilera pas, parce que les membres de B (et B lui-même) ne sont pas a déclaré avant A::A(). Le compilateur ne saura pas simplement ce que B est.

Si vous échangez les définitions de A et B, le code devrait compiler et fin de travail. En tant que tout est dans la même unité de traduction, il ne devrait pas y avoir de problèmes avec l'ordre d'initialisation, en supposant que le Définitions des membres statiques de précéder B définition de C::s_A. Les objets définis dans la même unité de traduction sont initialisés dans l'ordre de leur définition, ce qui signifie que les mises en A::A() temps, les membres statiques de B sont déjà initialisés. Il n'y a pas de potentiel de la faute de segmentation dans ce cas, tel que présenté.

Si vous obtenez une erreur de segmentation, vous devez être en train de faire quelque chose différemment. Ordre de définition est différente? Plusieurs unités de traduction peut-être? Post / décrire le code réel.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top