静的変数のコンストラクタで静的定数変数の値を取得
-
27-09-2019 - |
質問
私は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
が何であるかを知ることができません。
A
とB
の定義を交換する場合は、、その後、コードはコンパイルして、作業罰金する必要があります。長いすべてが同じ翻訳単位である限りとして、と仮定すると、初期化の順序で何か問題があってはならないことB
のに先行の静的メンバーのの定義のの定義のC::s_A
の。同じ翻訳単位で定義されたオブジェクトは、時間A::A()
が開始により、B
の静的メンバーが既に初期化されていることを意味し、その定義の順に初期化されます。提示この場合のセグメンテーションフォールトのための可能性はありません。
、あなたは違った何かをしなければなりません。定義の順序が違うのですか?複数の翻訳単位かもしれませんか?郵便/実際のコードを記述します。