이것만은 잊지 말자!
- 생성자 혹은 소멸자 안에서 가상 함수를 호출하지 말자
생성자나 소멸자 안에서 파생 클래스의 가상 함수를 호출하지 않음
이유
기본 클래스의 생성자가 호출될 동안 가상 함수는 절대 파생 클래스의 함수를 호출하지 않음
class MyClass
{
public:
MyClass() { print(); } // 링크 에러 발생
virtual void print() const = 0;
};
class MyAddClass : public MyClass
{
public:
virtual void print() const { cout << "MyAddClass" << '\n'; }
};
MyAddClass m;
파생 클래스 객체의 기본 클래스 부분이 생성되는 동안 그 객체의 타입은 기본 클래스
dynamic_cast, typeid를 사용하면 기본 클래스 취급
소멸자가 호출될 때도 파생 클래스의 소멸자 후 기본 클래스 소멸자에 진입할 때는 기본 클래스로 취급
해결방법
비가상 멤버 함수로 변경하고 파생 클래스 생성자에서 기본 클래스 생성자에 정보를 전달
static 함수로 선언하여 생성이 끝나기 전에 미초기화된 데이터 멤버를 접근할 위험을 방지
class MyClass
{
public:
MyClass (str) { print(str); }
print(const string str) const { cout << str; }
};
class MyAddClass : public MyClass
{
public:
MyAddClass(const string str) : MyClass(createString(str)) {}
private:
static string createString(....);
};
'C++ > Effective C++' 카테고리의 다른 글
Effective C++ 항목 11 operator=에서는 자기대입에 대한 처리가 빠지지 않도록 하자 (0) | 2024.07.02 |
---|---|
Effective C++ 항목 10 대입 연산자는 *this의 참조자를 반환하게 하자 (0) | 2024.07.02 |
Effective C++ 항목 8 예외가 소멸자를 떠나지 못하도록 붙들어 놓자 (0) | 2024.07.01 |
Effective C++ 항목 7 다형성을 가진 기본 클래스에서는 소멸자를 반드시 가상 소멸자로 선언하자 (0) | 2024.07.01 |
Effective C++ 항목 4 객체를 사용하기 전에 반드시 그 객체를 초기화 하자 (0) | 2024.06.26 |