コンテンツにスキップ

代入演算子

演算子オーバーロードの対象して代入演算子もあります。

代入演算子にはコピー代入演算子とムーブ代入演算子の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);  // ムーブ代入演算子を使用