簡體   English   中英

如何防止使用尚未構造的類成員?

[英]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,我剛剛修復了導致段錯誤的錯誤)。

如何防止這種情況發生?

我會同意其他人的建議,即設計者有責任確保對象在使用前已初始化。 對於您的情況,我看到了兩種解決方法:

首先(也是最簡單的),在類定義中顛倒ab的順序:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM