생성자나 소멸자에서 가상 함수 호출은 우리가 원하는 방식으로 동작하지 않는다.

왜 생성자에서 가상 함수를 호출하면 안 될까?

다음과 같은 주식 거래(Stock Transaction) 시스템이 있다고 가정해 보자.

class Transaction { // 모든 거래를 위한 기본 클래스 (Base class)
public:
    Transaction();
    virtual void logTransaction() const = 0; // 거래 기록을 남기는 가상 함수
};

Transaction::Transaction() { 
    logTransaction(); // ❌ 생성자에서 가상 함수 호출
}

소멸자에서는?

해결 법

  1. 가상 함수를 생성자가 아닌 생성이 끝난 후 호출하기
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;
    }
};

  1. 템플릿 메서드를 사용하여 안전하게 처리
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;
    }
};