생성자나 소멸자에서 가상 함수 호출은 우리가 원하는 방식으로 동작하지 않는다.
다음과 같은 주식 거래(Stock Transaction) 시스템이 있다고 가정해 보자.
class Transaction { // 모든 거래를 위한 기본 클래스 (Base class)
public:
Transaction();
virtual void logTransaction() const = 0; // 거래 기록을 남기는 가상 함수
};
Transaction::Transaction() {
logTransaction(); // ❌ 생성자에서 가상 함수 호출
}
Transaction의 생성자가 실행될 때, logTransaction()이 호출된다logTransaction() 이 호출 된다면. 실제 실행되는 함수는 derived class의 logTransaction() 이 아닌 기본 베이스 클래스의 함수가 호출된다.
class Transaction {
public:
Transaction() {
// 생성자에서 logTransaction()을 호출하지 않음!
}
virtual void logTransaction() const = 0;
};
class BuyTransaction : public Transaction {
public:
BuyTransaction() {
logTransaction(); // ✅ 생성 완료 후 호출
}
virtual void logTransaction() const override {
std::cout << "Logging Buy Transaction" << std::endl;
}
};
class Transaction {
public:
Transaction() {
init(); // init()을 통해 안전한 초기화 수행
}
virtual ~Transaction() = default;
protected:
virtual void init() {} // 파생 클래스에서 override 가능
};
class BuyTransaction : public Transaction {
protected:
virtual void init() override {
logTransaction(); // ✅ 안전한 시점에서 호출
}
virtual void logTransaction() const override {
std::cout << "Logging Buy Transaction" << std::endl;
}
};