class Widget {
private:
    int* data; // 동적 메모리 할당된 데이터
public:
    Widget(int value) { data = new int(value); }
    
    Widget& operator=(const Widget& other) {
        delete data;               // 기존 데이터 삭제
        data = new int(*other.data); // 새로운 데이터 복사
        return *this;
    }
};

Widget w(10);
w = w;  // 자기 자신에게 대입 (Self-assignment)

위 문제의 해결 방법

  1. 자기 자신인지 체크하기
Widget& operator=(const Widget& other) {
    if (this == &other) return *this; // 자기 자신이면 아무것도 하지 않음

    delete data;
    data = new int(*other.data);
    return *this;
}
  1. 예외 안전성까지 고려
Widget& operator=(const Widget& other) {
    int* newData = new int(*other.data); // 새 데이터를 먼저 생성
    delete data;                         // 기존 데이터 삭제
    data = newData;                      // 새 데이터로 교체
    return *this;
}
  1. Copy-and-Swap (가장 좋은 방법)
class Widget {
private:
    int* data;
public:
    Widget(int value) { data = new int(value); }
    ~Widget() { delete data; }

    void swap(Widget& other) { // 두 개의 객체를 교환하는 함수
        std::swap(data, other.data);
    }

    Widget& operator=(Widget other) { // 복사 생성자를 활용한 대입 연산자
        swap(other); // 복사본과 데이터를 교환
        return *this;
    }
};