質問

私はAのCSTRに、B :: SYMBOLがまだ初期化されていなかったので、以下のコードは、セグメンテーションフォールトをもたらすことを理解しています。しかし、なぜ?

は実際には、Aは、それぞれのIDにBのようなクラスのシンボルをマッピングするマップとして機能するオブジェクトです。 Cは、このマップ(A)静的-LYそれがクラス関数としてマッピングを提供することができるように保持しています。

Aの主な機能は、起動時に自身を初期化C用のマップとして機能します。どのように私は(PLSの#defineなし)私はまだコードでB :: IDとB :: SYMBOLを使用することができることを提供し、セグメンテーション違反せずにそれを行うことができるはずです?

(PS。私は警備員を含んで実装されていると仮定)。

//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)
    {
    }
役に立ちましたか?

解決

あるs_Aの使用遅延初期化。このかもしれない作品ます:

class C
{
public:
  static A& getA() { static A s_A; return s_A; }
};

それともます:

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;

どちらのソリューションは、スレッドセーフです。

他のヒント

どのようなセグメンテーションフォールトあなたが話しているの? Bのメンバー(と自分自身をB)は、のではありませんので、あなたのコードは、単純に、コンパイルされませんA::A()前にの宣言。コンパイラは、単にBが何であるかを知ることができません。

あなたはABの定義を交換する場合は、

、その後、コードはコンパイルして、作業罰金する必要があります。長いすべてが同じ翻訳単位である限りとして、と仮定すると、初期化の順序で何か問題があってはならないことBのに先行の静的メンバーのの定義の定義C::s_Aの。同じ翻訳単位で定義されたオブジェクトは、時間A::A()が開始により、Bの静的メンバーが既に初期化されていることを意味し、その定義の順に初期化されます。提示この場合のセグメンテーションフォールトのための可能性はありません。

あなたがセグメンテーションフォールトを取得している場合は、

、あなたは違った何かをしなければなりません。定義の順序が違うのですか?複数の翻訳単位かもしれませんか?郵便/実際のコードを記述します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top