![](/img/trans.png)
[英]How are static members of templated class constructed when a static function is called?
[英]how to prevent usage of class members not yet constructed?
我有以下課程:
class A
{
public:
A() { x = 0; std::cout<<"A default ctor()\n"; }
A(int x_) { x = x_; std::cout<<"A normal ctor()\n"; }
int x;
};
class B
{
public:
B() { std::cout<<"B ctor()\n"; }
private:
std::string str;
};
還有一個以對象A為參數創建對象B的函數:
B
createB(const A& a) {
std::cout<<"a int: "<<a.x<<"\n";
return B();
}
如果我設計一個類C,它具有類型A和B的成員,並且在構造A對象之前先構造了B對象, 但是使用A對象這樣做 ,它將在沒有警告的情況下進行編譯,但是會靜默地輸入一個錯誤:
class C
{
public:
C(): b(createB(a)), a(10) {}
private:
B b;
A a;
};
int main()
{
C c;
return 0;
}
當然,上面的示例是一個簡單的示例,但是我已經在現實世界中以更復雜的代碼看到了它(現在是星期五,晚上8:30,我剛剛修復了導致段錯誤的錯誤)。
如何防止這種情況發生?
我會同意其他人的建議,即設計者有責任確保對象在使用前已初始化。 對於您的情況,我看到了兩種解決方法:
首先(也是最簡單的),在類定義中顛倒a
和b
的順序:
class C
{
public:
C(): b(createB(a)), a(10) {}
private:
A a;
B b;
};
其次,如果您要真正強調它的初始化發生在其他成員的初始化之前,則可以將a
移至基類:
class CBase
{
protected:
CBase(): a(10) {}
protected:
A a;
};
class C : private CBase
{
public:
C(): b(createB(a)) {}
private:
B b;
};
我看到三種可能的選擇:
A
來構建之前被構造C
: class C
{
public:
C(const A& a) : a_(a), b_(a) {}
private:
A a_;
B b_;
};
A
構建“B”之前: 將B
的構造延遲到A
完成為止。 這樣可以阻止未定義的行為的發生,但是不會通過接口強制執行正確的行為(如選項1和3 那樣 )
class C
{
public:
C() : a_(/* construct as appropriate */)
{
b_.reset(new B(a_));
}
private:
A a_;
std::unique_ptr<B> b_;
};
B
包含(並公開) A
。 從一個簡單的例子來看,這似乎是可能的,但在現實生活中可能不是:
class B
{
public:
const A& my_a() {return a_;}
private:
// construct as appropriate (?)
A a_;
};
class C
{
private:
B b_;
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.