1

おそらく私は何も心配していません。私は、データ メンバーが RAII のイディオムに厳密に従うことを望んでいます。抽象基本クラスの保護されたポインター メンバーを null に初期化するにはどうすればよいですか?

null であることはわかっていますが、それが普遍的に理解されるようにした方がよいのではないでしょうか?

初期化コードを初期化子リストの外に置くと、実行されない可能性があります。このポインターをスタックに割り当てるためのアセンブリ操作の観点から考えると、マルチスレッド環境で (c'tor 本体と同じように) 中断することはできませんか、それともスタック拡張はアトミックであることが保証されていますか? デストラクタの実行が保証されている場合、プロセッサがアトミックに実行しなくても、スタック拡張にはそのような保証がないのでしょうか?

このような単純な質問が、どうしてこれほど広範に及ぶようになったのでしょうか? ありがとう。

すばらしい std:: ライブラリを避けることができれば、私はミニマリストの環境にいます。

4

2 に答える 2

3

非常に簡単です: 最善の方法は、スマート ポインターを使用することです。実際には標準を避けないでください。一般的に、平均的な実装よりも優れています。

class base{
public:
    base() : a(new int(5)) {}
protected:
    std::unique_ptr<int> a;
    virtual ~base() {} 
};

class child : public base {
     child() : base() {}
     ~child() {} //a will automatically be deleted
};

この場合、ポインターが子によって使用されない限り (これは多くの場合、優れた設計ではありません)、非公開にすることができます。

別の方法は、基本デストラクタで手動で削除することです

class base{
public:
    base() : a(new int(5)) { }    //base member init'd
protected:
    int* a;
    virtual ~base() { delete a;  } //base member destroyed
};
于 2012-02-26T23:23:53.770 に答える
3

おそらく、あなたはこれを考えすぎています。次の例では、基本メンバーが null に初期化されています。

struct Base
{
    virtual ~Base() = 0; // or make something else pure; this is just an example

    Base() : p() { }           // p initialized to null
    Base(Foo * q) : p(q) { }   // another option

protected:
     Foo * p;
};

struct Derived : private Base
{
    // no extra work needed

    // maybe something like this...
    Derived(int a, bool c) : Base(new Foo(a * (c ? 2 : 3))) { }
};

Base::p派生コンストラクターは最初に基本コンストラクターを呼び出し、それがゼロに初期化されると言います。

于 2012-02-26T23:28:15.657 に答える