-
Effective C++...8일지 2022. 6. 7. 07:52
객체 생성 및 소멸 과정 중에는 절대로 가상 함수를 호출하지 말자
파생 클래스의 초기화
파생 클래스의 기본 클래스 초기화 시 파생 클래스는 기본 클래스로 결정된다.
즉, 기본 클래스 초기화 시에는 typeid 같은 것을 사용하더라도 기본 클래스로 나타나게 되며 가상 함수를 호출한다면 기본 클래스의 가상 함수가 호출될 것이다.
class Transaction {
public:
Transaction();
virtual void logTransaction() const = 0; // 로그를 찍는 가상 함수가 있는 경우
};
Transaction::Transaction() {
logTransaction(); // 이 경우 Transaction의 logTransaction을 호출하게 된다.
}
class SellTransaction : public Transaction {public: virtual void logTransaction() const; // 로그 가상 함수를 파생 클래스에서 구현했으나};SellTransaction a; // 클래스 생성 시 기본 클래스부터 호출되므로 에러가 발생할 것이다.
공통된 함수를 안전하게 호출하는 방법
가상 함수를 생성자에서 호출하는 게 위험하므로 비가상 함수를 호출하도록 하는 대신 생성자의 인자로 필요한 정보를 받아올 수 있도록 하면 안전하게 공용 함수를 호출할 수 있게 된다.
class Transaction {
public:
explicit Transaction(const std::string& logInfo); // 생성자에서 필요한 정보를 받는다.
void logTransaction(cons std::string& logInfo) const; // 비가상 함수로 만든다.
};
Transaction::Transaction(const std::string& logInfo)
{
logTransaction(logInfo); // 받아온 정보를 이용해 함수를 호출한다.
}
class BuyTransaction : public Transaction {
public:
BuyTransaction(parameters)
: Transaction(createLogString(parameters)) { } // 필요한 정보를 만들어 기본 클래스에 전달한다.
private:
static std::string createLogString(parameters);
}