22

したがって、基本的にこのコードは次のとおりです。

class A {
};
class B { 
   B (const B& b) {}
public: 
   B (){}
   B (const A& a) {} 
};

int main()
{
   A a;
   B b1(a);  //OK
   B b2 = a; //Error
}

のエラーのみを生成しますB b2 = a。そして、そのエラーは

エラー:'B :: B(const B&)'はプライベートです

直接変換コンストラクターに加えてコピーコンストラクターを呼び出そうとするのはなぜですか?

エラーメッセージから、Bコピー構築に使用される一時的なものが作成されていることは明らかですが、なぜですか?これは標準のどこにありますか?

4

1 に答える 1

14
B b2 = a;

これは、コピー初期化として知られています。

次のことを行います。

  1. を使用してB、からタイプのオブジェクトを作成します。aB (const A& a)
  2. b2を使用して、作成した一時オブジェクトをにコピーしB (const B& b)ます。
  3. を使用して一時オブジェクトを破棄します~B()

発生するエラーは、ステップ1ではなく、ステップ2にあります。

これは標準のどこにありますか?

C ++ 03 8.5イニシャライザー
パラ14:

....
—宛先タイプが(おそらくcv修飾された)クラスタイプの場合 :
.....。

—それ以外の場合(つまり、残りのコピー初期化の場合)、ソースタイプから宛先タイプに、または(変換関数が使用される場合)その派生クラスに変換できるユーザー定義の変換シーケンスが、13.3で説明されているように列挙されます。 .1.4であり、過負荷解決(13.3)によって最適なものが選択されます。変換を実行できないか、あいまいな場合、初期化の形式が正しくありません。選択された関数は、初期化子式を引数として呼び出されます。関数がコンストラクターの場合、呼び出しは宛先タイプの一時的なものを初期化します。次に、呼び出しの結果(コンストラクターの場合は一時的なもの)を使用して、上記の規則に従って、コピー初期化の宛先であるオブジェクトを直接初期化します。場合によっては、実装では、初期化されるオブジェクトに直接中間結果を構築することにより、この直接初期化に固有のコピーを排除できます。12.2、12.8を参照してください。

于 2012-06-27T08:22:58.953 に答える