代入演算子¶
演算子オーバーロードの対象して代入演算子もあります。
代入演算子にはコピー代入演算子とムーブ代入演算子の2つがあります。
コピー代入演算子¶
コピー代入演算子は通常以下を満たすメンバ関数として定義します。
- 引数はコピー元となるオブジェクトの
const
左辺値参照 - 戻り値はコピー先オブジェクト (自オブジェクト) の左辺値参照
class Copyable { public: Copyable(); // デフォルトコンストラクタ Copyable& operator=(const Copyable& c); // コピー代入演算子 };
コピー代入演算子を使用するには次のようにします。
Copyable c1; // デフォルトコンストラクタでオブジェクト作成 Copyable c2; // デフォルトコンストラクタでオブジェクト作成 c2 = c1; // コピー代入演算子でコピー代入
一般にコピーコンストラクタとコピー代入演算子はセットで使用します。
class Copyable { public: Copyable(); // デフォルトコンストラクタ Copyable(const Copyable& c); // コピーコンストラクタ Copyable& operator=(const Copyable& c); // コピー代入演算子 };
コピー代入演算子を定義していないクラスでは コンパイラによって暗黙的にコピー代入演算子が定義されます。
暗黙的にコピー代入演算子が定義されないケース
コピー代入演算子を定義していないクラスであっても、 特定の条件を満たした場合には暗黙的なコピー代入演算子の定義は行われなくなります。
条件の一例として次のものがあります。
- コピー代入演算子が定義されていないメンバ変数をもつ
- 下記のいずれかが明示的に定義されている
- ムーブコンストラクタ
- ムーブ代入演算子
詳細は コピー代入演算子 - cppreference.com を参照してください。
ムーブ代入演算子¶
ムーブ代入演算子は通常以下を満たすメンバ関数として定義します。
- 引数はムーブ元となるオブジェクトの右辺値参照
- 戻り値はムーブ先オブジェクト (自オブジェクト) の左辺値参照
class Movable { public: Movable(); // デフォルトコンストラクタ Movable& operator=(Movable&& m); // ムーブ代入演算子 };
ムーブ代入演算子を使用するには次のようにします。
Movable m1; // デフォルトコンストラクタでオブジェクト作成 Movable m2; // デフォルトコンストラクタでオブジェクト作成 m2 = std::move(m1); // ムーブ代入演算子でムーブ代入
一般にムーブコンストラクタとムーブ代入演算子はセットで使用します。
class Movable { public: Movable(); // デフォルトコンストラクタ Movable(Movable&& m); // ムーブコンストラクタ Movable& operator=(Movable&& m); // ムーブ代入演算子 };
ムーブ代入演算子を定義していないクラスでは コンパイラによって暗黙的にムーブ代入演算子が定義されます。
暗黙的にムーブ代入演算子が定義されないケース
ムーブ代入演算子を定義していないクラスであっても、 特定の条件を満たした場合には暗黙的なムーブ代入演算子の定義は行われなくなります。
条件の一例として次のものがあります。
- ムーブ代入演算子が定義されていないメンバ変数をもつ
- 下記のいずれかが明示的に定義されている
- コピーコンストラクタ
- コピー代入演算子
- ムーブコンストラクタ
- デストラクタ
詳細は ムーブ代入演算子 - cppreference.com を参照してください。
初期化¶
C++ では代入と初期化が区別されます。
変数宣言と同時に使用する =
は代入ではなく初期化として扱われます。
コピー初期化¶
初期化をコピーによって行う場合、 コピー代入演算子ではなくコピーコンストラクタが使用されます。
Copyable c1; Copyable c2 = c1; // コピーコンストラクタを使用 Copyable c3; c3 = c2; // コピー代入演算子を使用
ムーブ初期化¶
初期化をムーブによって行う場合、 ムーブ代入演算子ではなくムーブコンストラクタが使用されます。
Movable m1; Movable m2 = std::move(m1); // ムーブコンストラクタを使用 Movable m3; m3 = std::move(m2); // ムーブ代入演算子を使用