2012-04-24 15 views
2

私は、実際に同じものへの参照であるかもしれないし、そうでないかもしれない2つの参照を取るParentクラスを持っています。それらが同じである。この場合、私は私の子クラスの初期化リスト内のシーケンスポイント警告が表示されます:初期化リストのシーケンスポイントの警告

class A 
{ 
    public: 
    A(int) {} 
    private: 
    A() {} 
}; 

class Parent 
{ 
    public: 
    Parent(A&, A&) {} 
}; 

class Child : public Parent 
{ 
    public: 
    Child() : 
     Parent(
      *(_A = new A(0)), 
      *(_A)) //Warning on this line 
    { 
    } 

    private: 
    A *_A; 
}; 

int main(int argc, char** argv) 
{ 
    return 0; 
} 

私はそのライン上のデリファレンスをした後に発生することが保証されていないからだと推測していますメモリが割り当てられています。それにもかかわらず、私の質問は、親やAのどちらにも変更を加えることなく、この周りには何かありますか?

答えて

4

親コンストラクタの2つの引数が呼び出される順序は保証されていません(その間にシーケンスポイントはありません)。*(_A = new A(0))を評価する前にコンパイラが*(_A)を合法的に評価することができます。

Aを動的に割り当てる必要がありますか?ない場合はあなたが行うことができます:

class Child : public Parent 
{ 
    public: 
    Child() : Parent(_a, _a), _a(0) {} 
    private: 
    A _a;    // _A is reserved for the implementation (compiler + library) 
}; 

1回の警告で、メンバーのアドレスを取得するか、それに参照を取ることが有効である一方で、それは_a前の基準や指針使用に未定義の動作ですメンバーは初期化され、Parentコンストラクターが完了した後にのみ発生します。つまり、Parentのコンストラクタは参照を格納するだけで、あなたは安全です(ブレードのエッジに沿って乗っていても出血していない)オブジェクトは使用しません。

Parentコンストラクタはそれを保存する以外に何のための基準を使用した場合、あなたはすでに構築さAオブジェクトへのポインタを受け取るためにChildクラスを変更することができます。

Child::Child(A* a) : Parent(*a, *a), _a(a) {} 
関連する問題