warning C4512: 'B' : assignment operator could not be generated
質問 1: なぜこの警告が表示されるのですか?
参照は、作成時に一度だけ初期化できます。Reference は作成された型変数の単なるエイリアスであり、引き続きそのままであるため、作成後に別の同じ型変数への参照を再割り当てすることはできません。再割り当てしようとすると、エラーが発生します。
通常、コンパイラはデフォルトですべてのクラスに暗黙的なビットごとの代入演算子を生成しますが、この場合class B
はメンバーとして参照があるm_a
ため、コンパイラが暗黙的な代入演算子を生成すると、参照を再代入できないという基本的なルールが破られます。そのため、コンパイラはこの警告を生成して、暗黙的な代入演算子を生成できなかったことを通知します。
質問 2: しかし、コンパイラは B b1 = b; に対してエラーを生成するべきではありません。発言も?
生成された警告とこの特定の操作はまったく関係がありません。
B b1 = b;
暗黙的な(@AndreyTによって正しく指摘されているように)コピーコンストラクターを呼び出しますB::B(const B&)
。暗黙のコピー コンストラクターは、クラスが既定で生成するメンバー関数の 1 つです。したがって、警告やエラーはありません。
質問 3: コピー コンストラクターは生成されましたが、代入演算子は生成されなかったようです。この 2 つは本質的に互いにリンクしていませんか?
いいえ、まったく関係ありません。はい、コンパイラはコピー コンストラクタを生成しましたが、上記の質問 1 の回答で指定された理由により、代入演算子を生成できませんでした。これは、メンバー参照m_a
がコンストラクター自体の本体で初期化される可能性があるためです。の場合のような割り当てではなく、作成時の初期割り当てです=
。
質問 4: 他の実装を生成できなかったときに、そのうちの 1 つのみの既定の実装を生成することは理にかなっていますか?
3つの質問への回答はこれに答えるようです。
コード例で実行されている操作を繰り返します。
B b(a);
変換コピー コンストラクターB::B(A&)
B b1 = b;
を呼び出す デフォルトのコピー コンストラクターを呼び出すB::B(const B&)
追加のシナリオを検討してください。
あなたがそれを持っB b1 = a;
ていれば、それが呼び出されるB::B(A&)
ので、再びエラーは発生しません。
B::B(A&)
ただし、が宣言されexplicit
ている場合、コンパイラはエラーをマークimplicit conversions
し、conversion function
.
ここで同じことを確認してください。