ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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);

    }


     

    댓글

Designed by Tistory.