int main()
{
	Point pos1(1, 2);
    Point pos2 = pos1; // 복사생성자 호출
    
    Point pos3(3, 4);
    pos3 = pos1; // 대입 연산자 호출
}
따로 정의하지 않아도 디폴트 대입연산자가 정의되어 있다.
디폴트 대입 연산자의 경우 멤버 대 멤버 복사가 선언되어 있다.
만약 다음과 같이 멤버변수가 선언되있다면
class Point
{
private:
	int num1;
    int num2;
}
대입연산자는 다음과 같이 선언되있다.
class Point
{
public:
	Point& operator=(const Point& ref)
    {
    	num1 = ref.num1;
        num2 = ref.num2;
        return *this;
    }
}
디폴트 대입 연산자는 멤버간 얕은 복사만 하기 때문에 깊은 복사가 필요한 경우 명시적으로 오버라이딩을 해야한다.
class Person
{
	char * name;
    int age;
public:
	Person(const char* name, int age) : age(age)
    {
    	int len = strlen(name)+1;
        this->name = new char[len];
        strcpy_s(this->name, len, name);
    }
    Person& operator=(const Person& ref) //깊은복사하는 대입연산자 오버로딩
    {
    	delete []name; //메모리 누수를 막기위해 메모리 해제
    	int len = strlen(ref.name)+1;
        name = new char[len];
        strcpy_s(name, len, ref.name);
        age = ref.age;
        return *this;
}
delete []name;을 먼저 해주는 이유는 대입 전에 원래 지정되있던 메모리를 사용할 일이 없기 때문에 삭제 해준다.
유도클래스의 대입연산자 오버로딩에서는 기초클래스의 대입연산자를 호출해줘야한다.
클래스 별로 자신의 멤버변수의 변경을 책임지는 것이 더 좋기 때문이다.
유도클래스의 디폴트 대입 연산자는 자동으로 기초클래스의 대입연산자를 호출해준다.
따라서 신경 안써도 된다.
class First
{
private:
	int num1, num2;
public:
	First(int num1, int num2) : num1(num1), num2(num2)
	{
	}
	First& operator=(const First& ref)
	{
		num1 = ref.num1;
		num2 = ref.num2;
		return *this;
	}
};
class Second : public First
{
private:
	int num3, num4;
public:
	Second(int a, int b, int c, int d) :First(a, b), num3(c), num4(d)
	{
	}
	Second& operator=(const Second& ref)
	{
		First::operator=(ref); // 기초클래스의 대입연산자를 호출해줘야한다.
		num3 = ref.num3;
		num4 = ref.num4;
		return *this;
	}
};

BBB 클래스의 경우 이니셜라이저를 사용해 mem을 초기화하고
CCC 클래스는 생성자 몸체에서 mem의 초기화를 하고 있다.
복사 생성자 호출
AAA의 void 생성자 호출
대입 연산자 호출
이니셜라이저 사용시 함수호출이 하나 줄어든걸 볼 수 있다.