#include <iostream>
using namespace std;
class CMyInteger {
public:
    // 변환 생성자
    CMyInteger(int param): data(param) {
        cout << "CMyInteger(int)" << endl;
    }
    // 복사 생성자
    CMyInteger(const CMyInteger &rhs): data(rhs.data) {
        cout << "CMyInteger(const CMyInteger &)" << endl;
    }
    // 이동 생성자
    CMyInteger(const CMyInteger &&rhs): data(rhs.data) {
        cout << "CMyInteger(const CMyInteger &&)" << endl;
    }
    // 형변환
    operator int() { return data; }
    // + 연산자
    CMyInteger operator+(const CMyInteger &rhs) {
        cout << "operator+" << endl;
        int temp = this->data + rhs.data;
        CMyInteger result(temp);
        return result;
    }
    // = 연산자(대입 연산자)
    CMyInteger operator=(const CMyInteger &rhs) {
        cout << "operator=" << endl;
        data = rhs.data;
        return *this;
    }
private:
    int data;
};
int main(int argc, char* argv[]) {
    cout << "***Begin***" << endl;
    CMyInteger a(0), b(1), c(2);
    a = b + c;
    // b+c 연산 수행
    // -> 임시 객체를 생성하기 위해 이동 생성자가 호출된다.
    // -> 생성된 임시 객체를 대입 연산자를 통해  a에 대입한다.
    cout << "****End****" << endl;
}
/*
출력:
    ***Begin***
    CMyInteger(int)
    CMyInteger(int)
    CMyInteger(int)
    operator+ -> + 연산자 호출
    CMyInteger(int) -> + 연산자 함수 내부의 result 객체 생성
    CMyInteger(const CMyInteger &&) -> 임시 객체를 생성하기 위해 이동 생성자가 호출된다.
    operator= -> 대입 연산자가 호출되어 임시 객체의 값을 대입한다.
    ****End****
*/
연산자 함수는 다중 정의가 가능하다.
CMyInteger타입과 int 타입의 사칙연산을 지원하고 싶다면 다음과 같이 정의하면 된다.
CMyInteger operator+(int param)
사실 cout 객체는 전역 변수로 존재하는 ostream 클래스의 인스턴스고, <<,>> 등의 연산자를 제공한다.
int main(int argc, char* argv[]) {
    CMyData a(0), b(5);
    a = a;
    cout << a << endl;
    return 0;
}
void operator=(const CMyData &rhs) {
    // r-value가 자기 자신이면 대입을 수행하지 않는다.
    if(this == &rhs) {
        return;
    }
    delete p_pnData;
    m_pnData = new int(*rhs.m_pnData);
}
int main(int argc, char* argv[]) {
    CMyData a(0), b(5), c(10);
    a = b = c;
    cout << a << endl;
    return 0;
}
b = c라는 연산의 반환값이 void이므로, a에는 어떠한 값도 대입되지 않는다.void를 l-value의 형식으로 취할 수 없다.CMyData& operator=(const CMyData &rhs) {
    if(this == &rhs) {
        return *this;
    }
    delete p_pnData;
    m_pnData = new int(*rhs.m_pnData);
    return *this;
}
// l-value로 사용되는 경우를 고려해야 한다.
// 일반적인 경우에는 첫 번째 선언이 사용된다.
int& operator[](int index);
// 두 번째 선언은 상수형 참조를 통해서만 호출할 수 있다.
// 오직 r-value로만 사용된다.
int operator[](int index) const;
int이다.(참이면 1, 거짓이면 0)int 클래스이름::operator==(const 클래스이름 &);
int 클래스이름::operator!=(const 클래스이름 &);
++--int operator++(); // 전위식
int operator++(int); // 후위식