zoukankan      html  css  js  c++  java
  • Effective C++ 笔记 —— Item 9: Never call virtual functions during construction or destruction.

    If Transaction had multiple constructors, each of which had to perform some of the same work, it would be good software engineering to avoid code replication by putting the common initialization code, including the call to logTransaction, into a private nonvirtual initialization function, say, init:

    class Transaction 
    {
    public:
        Transaction()
        {
            init();
        } // call to non-virtual...
        virtual void logTransaction() const = 0;
        //...
    private:
        void init()
        {
            //...
            logTransaction(); // ...that calls a virtual!
        }
    };

    This code is more insidious, because it will typically compile and link without complaint.In this case, because logTransaction is pure virtual in Transaction, most runtime systems will abort the program when the pure virtual is called (typically issuing a message to that effect). However, if logTransaction were a "normal" virtual function (i.e., not pure virtual) with an implementation in Transaction, that version would be called, and the program would merrily trot along, leaving you to figure out why the wrong version of logTransaction was called when a derived class object was created.

    There are different ways to approach this problem. One is to turn logTransaction into a non-virtual function in Transaction, then require that derived class constructors pass the necessary log information to the Transaction constructor. That function can then safely call the nonvirtual logTransaction. Like this:

    class Transaction 
    {
    public:
        explicit Transaction(const std::string& logInfo);
        void logTransaction(const std::string& logInfo) const; // now a non-virtual func
        //...
    };
    Transaction::Transaction(const std::string& logInfo)
    {
        //...
        logTransaction(logInfo); // now a non-virtual call
    } 
    
    class BuyTransaction : public Transaction 
    {
    public:
        BuyTransaction(parameters)
            : Transaction(createLogString(parameters)) // pass log info
        {
            //...
        } // to base class constructor
         // ...
    private:
        static std::string createLogString(parameters);
    };

    Things to Remember

    • Don't call virtual functions during construction or destruction, because such calls will never go to a more derived class than that of the currently executing constructor or destructor.
  • 相关阅读:
    网页制作之JavaScript部分3--事件及事件传输方式(函数调用 练习题 )重要---持续更新中
    网页制作之JavaScript部分 2
    网页制作之JavaScript部分 1
    css之display:inline-block与float区别(可以尝试用一下)
    边框圆角化方式(原文链接http://www.cnblogs.com/SJP666/p/4678730.html)
    网页制作之html基础学习5-background-position用法
    网页制作之html基础学习4-格式与布局
    网页制作之html基础学习3-css样式表
    网页制作之html基础学习2-标签
    程序员的成长必备
  • 原文地址:https://www.cnblogs.com/zoneofmine/p/15205006.html
Copyright © 2011-2022 走看看