2017-06-26 10 views
1

この例を考えてみます。メンバ初期化子リストの参照メンバのコンストラクタを呼び出す方法は?

class C {}; 

class B { 
public: 
    B(C& c) : c_(c) {}; 
private: 
    C& c_; 
}; 

class A { 
public: 
    A(C& c) : b(c) {}; 
private: 
    B& b; 
}; 

AクラスBの基準部材bを有しています。 Bには、クラスCの参照を取るコンストラクタがあります。 Aのコンストラクタは、クラスCの参照を受け取り、cで後者のコンストラクタを呼び出すことによってbを初期化しようとします。

しかし、打ち鳴らすには、次のメッセージを表示して文句を言う:

wtf.cpp:12:13: error: non-const lvalue reference to type 'B' cannot bind to a value of unrelated type 'C' 
    A(C& c) : b(c) {}; 
      ^~ 
1 error generated. 

それは打ち鳴らすが、私はbからcを割り当てたと思ったほとんどかのように聞こえるが、私の意図はcBのコンストラクタを呼び出すことです。私はここで間違って何をしていますか?

+4

を'を参照してください。 'A :: b' *は参考にする必要がありますか?どうして? –

+6

'A'は' B'への参照を持っています。 'B 'はどこにその参照をバインドしようとしていますか?その生涯は何ですか? –

+0

あなたはhttps://ideone.com/eW2nwZのような何かを非常に危険にする可能性があります。 – Stargateur

答えて

1

あなたが記述しているのは、イニシャライザリストに限らず、通常の参照の作成に限られます。以下はコンパイルしないでください:

class C 
{}; 

class B 
{ 
public: 
    B(C& c) 
    : c_(c) 
    {} 
private: 
    C& c_; 
}; 

int main() 
{ 
    C c; 
    B b0(c); // This works because you actually create an object of type B. 

    B& b1(c); // Error, cannot construct reference to B from C. 
    B& b2 = c; // Same as above, only a different notation. 
    // You cannot write a constructor of B to make these lines work, 
    // because you do not create an object of type B. 
} 

をクラスBの目的はCオブジェクトへの参照から構築することができるが、同じ参照を保持していません。参照は、同じタイプのオブジェクトまたは継承階層の下のタイプからのみ作成することができます。

これはまさに参照のポイントです。オブジェクトを作成しないでください。別の場所に作成されたオブジェクトの新しい名前を導入するだけです。

1

これはできません。実際には、参照は変更不可能なポインタの近くにあります。つまり、B&は、BクラスのオブジェクトまたはBのサブクラスのオブジェクトのみを参照できます。そして、参照の構築のようなものはありません。

参照から一時オブジェクトBを作成することはできますが、参照が初期化されるとすぐに参照オブジェクトが破棄されるため、一時オブジェクトで参照を初期化することはできません。

だから、実際のオブジェクトではありませんREF保存する必要があります:あなたはない:: bの `のためのB``の実際のインスタンスなしに、あなたがやりたいことができない

class A { 
    public: 
     A(C& c) : b(c) {}; 
    private: 
     B b; 
    }; 
関連する問題