반응형
0. 요약
- 컴파일러는 기본 생성자, 복사 생성자, 복사 대입 연산자, 소멸자를 암시적으로 만들 수 있다.
1. 컴파일러가 알아서 선언하는 멤버 함수
- 빈클래스가 선언되어 있으면 컴파일러는 아래 멤버 함수를 자동으로 생성한다.
- 복사 생성자(copy constructor)
- 복사 대입 연산자(copy assignment operator)
- 소멸자(destructor)
- 기본 생성자 : 생성자가 없을 때 생성됨
- 자동 생성된 함수는 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 => 복사 대입 연산자 호출
소멸자
- 상속한 기본 클래스의 소멸자가 가상이 아니면 비가상으로 생성됨
복사 생성자 자동 생성
- 아래 예는 복사 생성자가 자동 생성됨
- string은 자체 복사생성자가 있으므로, no2의 nameValue는 no1의 nameValue값을 가짐
- int형 no2의 objectValue는 no1의 비트를 그대로 복사해옴
template<typename T>
class NamedObject{
public:
NamedObject(const char* name, const T& value);
NamedObject(const std::string& name, const T& value);
private:
std::string nameValue;
T objectValue;
};
// 사용 부
NamedObject<int> no1("Smallest Prime Number", 2);
NmaedObject<int> no2(no1); // 복사 생성자 자동 생성됨
- 복사 대입 연산자가 생성되지 않는 예
- 최종 결과 코드가 적법하지 않거나 resonable하지 않으면 자동 생성하지 않음
- 아래 예시에서 자동생성되지 않고 컴파일 거부됨.
- 참조자를 데이터 멤버로 가지고 있으면, 직접 복사 대입 연산자 정의 필요!
template<class T>
class NamedObject{
public:
NamedObject(std::string& name, const T& value);
private:
std::string& nameValue; // 참조자
const T objectValue; // 상수 멤버
};
// 사용 부
std::string newDog("Persephone");
std::string oldDog("Satch");
NamedObject<int> p(newDog, 2);
NamedObject<int> s(oldDog, 36);
p = s; // 가능한가?
참고
- Effective C++
반응형
'C++ > Effective C++' 카테고리의 다른 글
[Effective C++] 7. 다형성을 가진 기본 클래스에서는 소멸자를 반드시 가상 소멸자로 선언하자. (0) | 2021.03.15 |
---|---|
[Effective C++] 6. 컴파일러가 만들어낸 함수가 필요없으면 확실히 이들의 사용을 금해버리자. (0) | 2021.03.15 |
[Effective C++] 4. 객체를 사용하기 전에 반드시 그 객체를 초기화하자 (0) | 2021.03.15 |
[Effective C++] 3. 낌새만 보이면 const를 들이대 보자 (0) | 2021.03.15 |
[Effective C++] 2. #define을 쓰려거든 const, enum, inline을 떠올리자 (0) | 2021.03.15 |