aPoint = anotherPoint;
Point::operator=
この行は、 (代入演算子) の呼び出しをトリガーします。これは、コンパイラが既定の実装を生成するために存在します。この既定の実装は、クラスのすべてのメンバーに対して代入操作を実行するだけでなくVector3::operator=
、基本クラスの代入演算子である を呼び出します。これは、 のメンバー関数でVector3
あるため、コピーを作成するすべてのプライベート メンバーにアクセスできます。
(編集) この回答を裏付ける C++11 標準からの引用:
(§12.8/28) 非共用体クラス X の暗黙的に定義されたコピー/移動代入演算子は、そのサブオブジェクトのメンバー単位のコピー/移動代入を実行します。X の直接基底クラスは、base-specifier-list での宣言の順序で最初に割り当てられ、次に X の直接の非静的データ メンバーが、クラス定義で宣言された順序で割り当てられます。 . x を関数のパラメーターにするか、move 演算子の場合はパラメーターを参照する xvalue にします。各サブオブジェクトは、そのタイプに適した方法で割り当てられます。
— サブオブジェクトがクラス型の場合、サブオブジェクトをオブジェクト式として、 x の対応するサブオブジェクトを単一の関数引数として使用して operator= を呼び出した場合と同様 (明示的な修飾による場合と同様。つまり、考えられるすべての仮想オーバーライドを無視する)より派生したクラスの関数);
— サブオブジェクトが配列の場合、要素の型に適した方法で各要素が割り当てられます。
— サブオブジェクトがスカラー型の場合、組み込み代入演算子が使用されます。
他の(現在は部分的に削除された)回答のいくつかは、割り当て操作によって実行されるビットごとのコピーのアイデアに言及しました。これにはいくつかの真実があります。クラスまたは構造体が POD (plain old data) 型を定義する場合、それはすべての実用的な目的で C 構造体と同じです。その場合は を実行することでコピーmemcpy
できますので、代入演算は基本的にビットごとのコピーと同等と考えることができます。しかし、これが有効な考え方である理由は、上記の §12.8/28 であり、POD 以外のタイプにも当てはまります。
また、コードからは、データ型が POD であることが必ずしも明確ではないことに注意してください。基本クラスでコンストラクターなどについて言及しました。これに重要なコピーコンストラクター、代入演算子、または仮想関数が含まれる場合、データ型は POD ではなくなります。
コメントの質問について: 派生クラスの実装内から基本クラスの代入演算子を呼び出すには、次のように呼び出します。
struct Base
{
};
struct Derived : Base
{
Derived &operator=(const Derived &other)
{ Base::operator=(other); return *this; }
};