©️

C++ 代入演算子

2024/10/08に公開

代入演算子

  • オブジェクトの既存のデータを新しいデータで上書きする際に呼び出される演算子(operator=)
  • 戻り値は自身のオブジェクト(*this)への参照を返す
  • 代入演算子を明示的に定義しない場合、コンパイラがデフォルトの浅いコピーを行う代入演算子を自動生成する
  • クラスで代入演算子を使用させたくない場合は、operator= を = delete; として無効化することができる
    無効化した状態で代入演算子を使おうとすると、コンパイル時にエラーが発生する

サンプルコード

#include <iostream>
#include <cstring>

class MyString {
private:
    char* data;  // 動的に確保された文字列データを指すポインタ
    int size;    // 文字列の長さ

public:
    // コンストラクタ
    MyString(const char* str) {
        size = std::strlen(str) + 1;  // 終端文字 '\0' を含む
        data = new char[size];
        std::strcpy(data, str);  // 文字列をコピー
        std::cout << "Constructor: Memory allocated for string \"" << data << "\".\n";
    }

    // コピーコンストラクタ(深いコピー)
    MyString(const MyString& other) {
        size = other.size;
        data = new char[size];
        std::strcpy(data, other.data);  // 文字列をコピー
        std::cout << "Copy Constructor: Memory copied for string \"" << data << "\".\n";
    }

    // デストラクタ(動的メモリの解放)
    ~MyString() {
        delete[] data;  // メモリ解放
        std::cout << "Destructor: Memory deallocated.\n";
    }

    // 代入演算子(深いコピーを行う)
    MyString& operator=(const MyString& other) {
        std::cout << "Assignment Operator: Assigning memory.\n";

        // 自己代入のチェック
        if (this == &other) {
            return *this;  // 自己代入の場合は何もしない
        }

        // 既存のデータを解放
        delete[] data;

        // 新しいデータをコピー
        size = other.size;
        data = new char[size];
        std::strcpy(data, other.data);  // 文字列をコピー

        return *this;  // 代入後の自分自身を返す
    }

    // 代入演算子を無効化するには
    // MyString& operator=(const MyString& other) = delete;

    // 文字列の表示
    void printData() const {
        std::cout << "String: " << data << std::endl;
    }
};

int main() {
    // オブジェクトを作成
    MyString str1("Hello, world!");
    str1.printData();

    // コピーコンストラクタでオブジェクトを作成
    MyString str2 = str1;  // コピーコンストラクタが呼ばれる
    str2.printData();

    // 別のオブジェクトを作成
    MyString str3("Goodbye!");
    str3.printData();

    // 代入演算子を使用してstr3にstr1を代入
    str3 = str1;  // 代入演算子が呼ばれる
    str3.printData();

    return 0;
}

実行結果

Constructor: Memory allocated for string "Hello, world!".
String: Hello, world!
Copy Constructor: Memory copied for string "Hello, world!".
String: Hello, world!
Constructor: Memory allocated for string "Goodbye!".
String: Goodbye!
Assignment Operator: Assigning memory.
String: Hello, world!
Destructor: Memory deallocated.
Destructor: Memory deallocated.
Destructor: Memory deallocated.

Discussion