객체지향 C++에서 클래스 안에 직접 선언해 넣지 않으면 컴파일러가 저절로 선언해 주도록 하는 맴버 함수들 이 있다.
- copy constructor
- copy assignment opeartor
- destructor
- default constructor
이때 이 맴버함수들은 모두 기본형, public, inline 함수이다.
컴파일러가 만들어주는 이 함수들은 무슨역할을 할까?
=> 컴파일러에게 "배후의 코드"를 깔 수 있는 자리를 마련하는 것이다.
배후의 코드 = base class 및 non-static member의 생성자, 소멸자를 호출하는 코드
이 때 소멸자는 derived class 가 상속한 base class의 소멸자가 virtual로 되있지 않으면 역시 non-virtual 소멸자로 만들어진다는 점
복사 생성자, 복사 대입생성자는? => 원본 객체의 non-static member들을 copy할 객체쪽으로 복사하는 것이다.
생성자가 선언되있음 => 기본생성자는 만들어지지 않음
복사 생성자는 생성되있지 않기 때문에, 기본 복사 생성자 생성 및 호출
기본 복사 생성자는 어떻게 동작할까?
=> no1.nameValue와 no1.objectValue를 사용해 no2.nameValue와 no2.objectValue를 초기화 해야한다.
nameValue 의 type은 string, 표준 string type은 자체 복사 생성자가 있으므로 no2.nameValue의 초기화는 string의 복사 생성자에 no1.nameValue를 넘겨 호출한다.
string nameValue(no1.nameValue); 이렇게 동작
objectValue는 built-in type 이므로 복사 생성자가 없다. 그냥 각 bit를 복사하고 끝남
int objectValue(no1.obejctValue);
기본 복사 대입 연산자는 어떻게 동작할까?
근본적인 동작원리는 기본 복사 생성자와 같음
하지만 기본 복사 대입 연산자는 몇가지 조건이 통과되어야 생성됨
아까랑 다른게 nameValue가 string이 아니라 string& 이다. 즉 참조자로 선언됨
근본적인 원리가 기본 복사 생성자와 같다면
p = s; 에서 p 객체에서는 p.nameValue = s.nameValue; 가 일어 나야됨 => 말이 안된다.
p.nameValue는 이미 newDog을 가르키고 있기 때문이다.
C++ 참조자는 원래 자신이 참조하고 있는 것과 다른 객체를 참조할 수 없다!!! 즉 갈아타기 안됨
참조자를 데이터 맴버로 갖고 있는 클래스에 대입 연산 지원하려면, 우리가 직접 복사 대입 연산자를 정의해줘야한다. >> 이게 기본 복사 대입 연산자의 생성 조건임, 조건에 어긋나면 컴파일 에러다.
데이터 맴버가 상수 객체 인 경우( const T objectValue; )에도 비슷하게 동작한다.
정리하 데이터 맴버가 참조자, 상수 객체 인 경우 직접 복사 대입 연산자를 정의해야 한다.
그리고 복사 대입 연산자를 private으로 선언한 base class로부터 상속받은 derived class의 경우에도 기본 복사 대입 연산자를 생성할 수 없다.
- 컴파일러는 경우에 따라 클래스에 대해 기본 생성자, 복사 생성자, 복사 대입 연산자, 소멸자를 암시적으로 만들어 놓는다.
'Effective C++ > 2. 생성자, 소멸자 및 대입 연산자' 카테고리의 다른 글
항목 10: 대입 연자는 *this의 참조자를 반환하게 하자 (0) | 2021.04.24 |
---|---|
항목 9: 객체 생성 및 소멸 과정 중에는 절대로 가상함수를 호출하지 말자 (0) | 2021.04.24 |
항목 8: 예외가 소멸자를 떠나지 못하도록 붙들어 놓자 (0) | 2021.04.24 |
항목 7: 다형성을 가진 클래스에서는 소멸자를 반드시 가상 소멸자로 선언하자 (0) | 2021.04.24 |
항목 6: 컴파일러가 만들어낸 함수가 필요없으면 확실히 이들의 사용을 금해 버리자. (0) | 2021.04.24 |