我需要派生從類基的一類子與下列要求:構造一個對象,把它傳遞給基類的構造保持其壽命的控制
- 階級基礎構造函數接受一個引用對象Foo類。
- Foo類的對象應該具有與Child類的對象相同的生命週期。
- Foo,Child和Base的構造函數可以拋出,代碼應該充分地破壞到目前爲止創建的內容。
- 代碼是多線程的,孩子的許多構造函數可以同時調用
- Foo沒有拷貝構造函數,沒有默認構造函數。
(也有一些相似之處How to remind a param passed to the base class constructor? 但是異常安全幾乎沒有在上面提到的問題討論)
儘管實現它,我遇到以下困難:
A.這似乎自然有類Foo的對象是兒童中的一員
class Base {
public:
Base(Foo& foo);
};
class Child: public Base {
public:
Child(int par);
private:
Foo m_foo;
};
不過,我現在該如何初始化它在兒童利弊tructor?
Child::Child(int par):
Base(Foo(par)),
m_Foo(par) ...
這將通過臨時基類構造函數(它會甚至編譯?),然後初始化m_Foo分別。這不好。
如果沒有要求#4,#5,我可以用一個靜態方法,共同構建富時基本被調用,然後將它傳遞給m_Foo:
Foo Child::s_Helper(int par) {
if (!s_FooConstructed) {
s_Foo = Foo(par);
s_FooConstructed = true;
}
return s_Foo;
}
我喜歡使用的unique_ptr或shared_ptr的作爲子類成員:
class Child: public Base {
public:
Child(int par);
private:
unique_ptr<Foo> m_Foo;
bool m_IsFooConstructed;
unique_ptr<Foo> x_FooHelper(int par);
};
Child::Child(int par):
Base(x_FooHelper(par)),
m_Foo(x_FooHelper(par))
{}
unique_ptr <Foo> Child::x_FooHelper(int par)
{
if(!m_FooConstructed) {
m_Foo.reset(new Foo(par)); ///< Problem here
m_FooConstructed = true;
}
return m_Foo;
}
然而,這裏m_Foo不是在x_FooHelper被調用的時候建造... 用相同的shared_ptr
我可以創造,而不是一個指針:但是這裏
class Child: public Base {
public:
Child(int par);
private:
Foo* m_Foo;
bool m_IsFooConstructed;
Foo* x_FooHelper(int par);
};
Child::Child(int par):
Base(*x_FooHelper(par)),
m_Foo(x_FooHelper(par))
{}
Foo* Child::x_FooHelper(int par)
{
if(!m_FooConstructed) {
m_Foo = new Foo(par);
m_FooConstructed = true;
}
return m_Foo;
}
,如果基本構造函數拋出,美孚已經創建,因爲它是由原始指針(m_Foo)保留了它不會被破壞〜孩子也不會調用。我能做什麼?
輝煌!非常感謝! – mzu