대입 연산자
디폴트 대입 연산자
- 복사 생성자뿐 아니라 대입 생성자도 정의하지 않으면 디폴트 대입 연산자가 생성된다.
- 디폴트 대입 연산자는 멤버대 멤버의 얕은 복사를 진행한다.
- 연산자 내에서 동적 할당을 한다면, 깊은 복사를 해야 한다면 직접 정의해야 한다.
복사 생성자 호출 예시)
int main()
{
Point pos1(5, 7);
Point pos2 = pos1;
}
대입 생성자 호출 예시)
int main()
{
Point pos1(5, 7);
Point pos2;
pos2 = pos1;
}
복사 생성자와 유사한 만큼 유사한 문제점(똑같다)과 유사한 해결책을 가지고 있다.
바로 문자열을 멤버로 가지게 될 때 대입한 객체와 대입된 객체가 하나의 문자열을 참조하는 상황이 발생한다.
해결책은
1. 대입되는 객체가 가지고 있던 문자열을 메모리 해제하고
2. 깊은 복사를 진행하면 된다.
Person& operator=(const Person& ref)
{
delete[] name;
this->name = new char[strlen(ref.name) + 1];
strcpy(this->name, ref.name);
age = ref.age;
return *this;
}
상속에서 대입 연산자
- 유도 클래스에서 대입연산자를 정의하지 않으면 기초 클래스의 대입연산자가 호출된다.
- 유도 클래스의 대입 연산자가 기초 클래스의 대입 연산자를 호출하지 않으면 기초 클래스의 대입 연산자가 호출되지 않는다.
이니셜라이저를 통한 성능향상
#include <iostream>
using namespace std;
class AAA
{
private:
int num;
public:
AAA(int n=0): num(n)
{
cout<<"AAA(int n=0)"<<endl;
}
AAA(const AAA &ref): num(ref.num)
{
cout<<"AAA(const AAA & ref)"<<endl;
}
AAA & operator=(const AAA &ref)
{
num=ref.num;
cout<<"operator=(const AAA &ref)"<<endl;
return *this;
}
};
class BBB
{
private:
AAA mem;
public:
BBB(const AAA & ref)
: mem(ref)
{ }
};
class CCC
{
private:
AAA mem;
public:
CCC(const AAA & ref)
{
mem=ref;
}
};
int main(void)
{
AAA obj1(12);
cout<<"*********************"<<endl;
BBB obj2(obj1);
cout<<"*********************"<<endl;
CCC obj3(obj1);
return 0;
}
결과
AAA(int n=0)
*********************
AAA(const AAA & ref)
*********************
AAA(int n=0)
operator=(const AAA &ref)
이니셜라이저를 이용해서 초기화를 하면 선언과 동시에 초기화가 이뤄지는 형태로 바이너리 코드가 생성된다.
= AAA의 복사 생성자만 호출됨
대입을 이용해서 초기화를 하면 선언과 초기화가 별도의 문장으로 진행하는 바이너리 코드가 생성된다.
= AAA의 생성자와 대입 연산자가 호출됨
'프로그래밍 언어 > 열혈 C++' 카테고리의 다른 글
11-3 연산자 오버로딩2 (0) | 2022.03.18 |
---|---|
11-2 연산자 오버로딩2 (0) | 2022.03.17 |
10-1. 연산자 오버로딩 1 (0) | 2022.03.14 |
10. 연산자 오버로딩 1 (0) | 2022.03.13 |
08 상속과 다형성 by 윤성우의 열혈 C++ (0) | 2022.03.08 |