オブジェクトの移動、移動コンストラクター、および移動代入演算子

1. オブジェクトの移動とは

    オブジェクトの移動とは、使用されなくなったオブジェクト A から有用なデータを抽出することです。新しいオブジェクト B を構築する場合、オブジェクト内のデータを再構築する必要はありませんが、使用されなくなったオブジェクト A からデータが抽出されます。有用なデータは、オブジェクト B を構築するときに使用されます。

2. コンストラクターの移動

1. なぜ移動コンストラクターが必要なのでしょうか?

    コピー コンストラクターとオーバーロードされた代入演算子があり、どちらもオブジェクト データのコピーを完了できることは以前に知っていましたが、オブジェクト データが非常に大きい場合、コストが非常に高くなります。そこで、C++11 では、この問題を解決するために使用される移動コンストラクターが提案されています。

2. 移動コンストラクターのデモ

    次のコードは、移動コンストラクターを示しています。

#include <iostream>
using namespace std;

class MyClass {
public:
    MyClass() { // 默认构造函数
        cout << "Use MyClass()" << endl;
    }
    MyClass(const MyClass& other) { // 复制构造函数
        cout << "Use MyClass(const MyClass& other)" << endl;
    }
    MyClass& operator=(const MyClass& other) { // 重载赋值运算符
        cout << "Use MyClass& operator=(const MyClass& other)" << endl;
    }
    MyClass(MyClass&& other) { // 移动构造函数
        cout << "Use MyClass(MyClass&& other)" << endl;
    }
    ~MyClass() { // 析构函数
        cout << "MyClass Destoryed" << endl;
    }
};

MyClass getMyClass() {
    MyClass my1;
    return my1;
}

int main() {
    MyClass my1;
    MyClass my2 = my1;
    MyClass my3(std::move(my2));

    return 0;
}

    main() 関数では、最初の行はデフォルト コンストラクターを呼び出し、2 行目はコピー コンストラクターを呼び出し、3 行目は std::move 関数を使用します。これは my2 を左辺値から右辺値に変更するため、呼び出しはコンストラクターを移動します。この例は、move コンストラクターの使い方を簡単に示したものであり、実際には「移動」の処理を関数内に実装する必要があります。

3. 移動代入演算子

    移動代入演算子は移動コンストラクタと同じです。代入演算子に基づいて関数パラメータを右辺値に変更するだけです。次に、移動代入演算子の簡単な使用例を示します。

#include <iostream>
using namespace std;

class MyClass {
public:
    MyClass() { // 默认构造函数
        cout << "Use MyClass()" << endl;
    }
    MyClass(const MyClass& other) { // 复制构造函数
        cout << "Use MyClass(const MyClass& other)" << endl;
    }
    MyClass& operator=(const MyClass& other) { // 重载赋值运算符
        cout << "Use MyClass& operator=(const MyClass& other)" << endl;
    }
    MyClass(MyClass&& other) noexcept { // 移动构造函数
        cout << "Use MyClass(MyClass&& other)" << endl;
    }
    MyClass& operator=(MyClass&& other) noexcept { // 移动赋值运算符
        cout << "Use MyClass& operator=(MyClass&& other)" << endl;
    }
    ~MyClass() { // 析构函数
        cout << "MyClass Destoryed" << endl;
    }
};

MyClass getMyClass() {
    MyClass my1;
    return my1;
}

int main() {
    MyClass my1;
    MyClass my2;
    my2 = std::move(my1);

    return 0;
}

 上記のコードでは、移動コンストラクター関数と移動代入演算子関数の最後にシンボル noexc を追加しました。これも同様です。

C++11 で新たに追加されたキーワード。その機能は、移動コンストラクターと移動代入演算子が例外をスローしないことをコンパイラーに通知することです (コンパイラーの効率を向上させるため)。それは習慣です、覚えておいてください!

4. 総合的なモバイル操作

    合成された移動操作とは、場合によっては、コンパイラが移動コンストラクターと移動代入演算子を自動的に合成することを意味します。合成問題の概要は次のとおりです。

  • クラス (MyClass) が独自のコピー コンストラクター、オーバーロードされた代入演算子、またはデストラクター (これら 3 つのいずれか) を定義している場合、コンパイラーは移動コンストラクターと移動代入演算子を合成しません。

  • クラスが移動コンストラクターと移動代入演算子を提供しない場合、代わりにコピー コンストラクターとオーバーロードされた代入演算子が自動的に使用されます。

  • クラスが独自のコピー コンストラクター、オーバーロードされた代入演算子、デストラクターを定義しておらず、クラスのすべての非静的メンバーが移動できる場合、コンパイラーは移動コンストラクターとクラス シンボルの移動代入演算を合成します。

おすすめ

転載: blog.csdn.net/hu853712064/article/details/130559622