항목 05 C++가 은근슬쩍 만들어 호출해버리는 함수들
5.1 컴파일러가 선언하는 디폴트 멤버 함수
- 컴파일러가 기본으로 선언하는 멤버 함수는 다음과 같다.
- 생성자(constructor)
- 복사 생성자(copy constructor)
- 소멸자(destructor)
- 복사 대입 연산자(copy assignment operator)
- 컴파일러가 만드는 함수는 모두 기본형(default)이고 public 멤버이며 inline 함수다.
class Empty { };
class Empty {
public:
Empty() { ... };// 디폴트 생성자
Empty(const Empty& rhs) { ... };// 디폴트 복사 생성자
~Empty() { ... };// 디폴트 소멸자
Empty& operator=(const Empty& rhs) { ... };// 디폴트 복사 대입 연산자
};
Empty e1;// 디폴트 생성자, 디폴트 소멸자 조건
Empty e2(e1);// 디폴트 복사 생성자 조건
e2 = e1;// 디폴트 복사 대입 연산자 조건
■ 5.1.1 디폴트 생성자와 디폴트 소멸자
- 디폴트 생성자와 디폴트 소멸자는 컴파일러에게 배후의 코드를 깔 수 있는 자리를 마련한다.
- 부모 클래스 및 비정적(non-static) 데이터 멤버의 생성자와 소멸자를 호출하는 코드가 이곳에 생긴다.
- 부모 클래스가 가상 소멸자로 되어있으면 역시 가상 소멸자로 만들어진다.
■ 5.1.2 디폴트 복사 생성자와 디폴트 복사 대입 연산자
- 디폴트 복사 생성자와 디폴트 복사 대입 연산자는 원본 객체의 비정적 데이터를 사본 객체로 복사한다.
template<typename T>
class NamedObject {
public:
// 사용자가 정의한 생성자
NamedObject(const string& name, const T& value)
: nameValue(name), objectValue(value) {
cout << "NamedObject 생성자" << endl;
}
// 디폴트 복사 생성자
NamedObject(const NamedObject& src)
: nameValue(src.nameValue), objectValue(src.objectValue) { }
private:
string nameValue;
T objectValue;
};
NamedObject<int> no1("Smallest Prime Number", 2);
NamedObject<int> no2(no1);// 디폴트 복사 생성자를 호출합니다.
- 디폴트 복사 생성자와 디폴트 복사 대입 연산자는 코드가 적법(legal) 하고 이치에 닿아야(reasonable)만 자동으로 생성된다.
- 데이터 멤버가 참조자인 경우, C++의 참조자는 원래 자신이 참조하고 있는 것과 다른 객체를 참조할 수 없다.
- 데이터 멤버가 상수인 경우, 상수 멤버를 수정하는 것은 문법에 어긋난다.
- 참조자와 상수 데이터 멤버를 처리할 수 없으므로 아예 컴파일을 거부한다.
template<typename T>
class NamedObject {
public:
NamedObject(string& name, const T& value) : nameValue(name), objectValue(value) {
cout << "NamedObject 생성자" << endl;
}
private:
string& nameValue;// 레퍼런스 데이터 멤버
const T objectValue;// const 데이터 멤버
};
string newDog("Persephone");
string oldDog("Satch");
NamedObject<int> p(newDog, 2);
NamedObject<int> s(oldDog, 36);
p = s;// 컴파일 오류!
NOTE
① 컴파일러는 경우에 따라 클래스에 기본 생성자, 소멸자, 복사 생성자, 복사 대입 연산자를 암시적으로 만들어 놓을 수 있다.
'Object Oriented Programming(C++) > Effective C++' 카테고리의 다른 글
Effective C++ | 항목 07 다형성을 가진 부모 클래스에서는 소멸자를 반드시 가상 소멸자로 선언하자 (0) | 2021.08.29 |
---|---|
Effective C++ | 항목 06 컴파일러가 만들어낸 함수가 필요 없으면 확실히 이들의 사용을 금해버리자 (0) | 2021.08.26 |
Effective C++ | 항목 04 객체를 사용하기 전에 반드시 그 객체를 초기화하자 (0) | 2021.08.26 |
Effective C++ | 항목 03 낌새만 보이면 const를 들이대보자 (0) | 2021.08.26 |
Effective C++ | 항목 02 #define을 쓰려거든 const, enum, inline을 떠올리자 (0) | 2021.08.21 |
댓글