2

私の問題は、次の例で非常に簡単に説明できます。

http://pastebin.com/VDBE3miY

class Vector3
{
  float                   _x;
  float                   _y;
  float                   _z;

public :
 /// constructors and stuff

};

class Point : public Vector3
{
// some BS
  Point(float _x):Vector3(float _x)
  {}
};

main()
{
   Point aPoint(3);
   Point anotherPoint(4);

   // WHY DOES THIS WORK and copy _x,_y & _z properly
   aPoint = anotherPoint;
}

=基本的に、派生クラスの for が_x_yおよびをコピーできる理由を理解するのに途方に暮れ_zています。これらはプライベートであるため、アクセスできないはずです。

4

3 に答える 3

5
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; }
};
于 2012-11-26T05:56:13.033 に答える
0

Vector3 のデフォルトのコピー演算子が呼び出されるため (浅いコピー)。

于 2012-11-26T05:47:15.617 に答える
0

コンパイラが代入演算子を生成するため

Point& operator=(Point const& rhs)
{
    Vector3::operator=(rhs);
    return *this;
}

Vector3& operator=(Vector3 const& rhs)
{
   // A class is a friend of irself.
   // So an object of Type A can read any other object of type A
   _x = rhs._x;
   _y = rhs._y;
   _z = rhs._z;
   return *this;
}
于 2012-11-26T06:17:23.013 に答える