前一段時間,我用一組嵌套類編寫了一些代碼。今天看看它,我想知道爲什麼它編譯時,我實例化類型的對象C.這段代碼爲什麼編譯時不會抱怨構造函數?
我的困惑是這樣的。 B有一個私人構造函數。這個構造函數的實現關心A的構造,但是A的構造需要B的一個實例。我覺得它是一個雞和雞蛋的場景。 B的建設需要建造A,這需要建造B等等。
我有以下的類 - 剝離右後衛演示問題:
// ******* A ******** //
class A {
public:
A(A& _Parent, int id);
private:
A& Parent;
};
inline A::A(A& _Parent, int id)
: Parent(_Parent)
{
}
// ******* B ******** //
class B:public A {
public:
static B& GetInstance();
private:
B();
};
inline B::B()
: A(B::GetInstance(), 0)
{
}
inline B& B::GetInstance()
{
static B b;
return b;
}
// ******* C ******** //
class C:public A {
public:
C();
};
inline C::C()
: A(B::GetInstance(), 0)
{
}
是的。我認爲這是不確定的行爲,但像大多數編譯器實現靜態函數/內部範圍對象的建設,這滑過裂縫,實際工作... –
注:也許這只是你的樣品中存在的問題,而不是真實的代碼;但是會導致未定義行爲將靜態對象放入內聯函數中(因爲靜態對象對於不同的翻譯單元將不同,但內聯函數對於所有單元必須相同)。希望在真正的代碼中,'B :: GetInstance()'沒有在頭文件中實現。作爲一個經驗法則,儘量避免提及任何靜態對象的內聯函數 –
有了'gcc'這也引發運行時異常[__gnu_cxx :: recursive_init_error(https://gcc.gnu.org/onlinedocs/gcc- 4.6.3 /的libstdC++/API/a00064.html)。所以即使這個問題沒有在編譯時被捕獲,初始化也會失敗。 – Jonesinator