• Effective C++ 条款09:绝不在构造和析构过程中调用virtual函数


    规则一 在base class构造期间,virtual函数不是virtual函数

    class Transaction {								// 所有交易的base class
    public:
    	Transaction();
    	virtual void logTransaction() const = 0;	// 做出一份因类型不同而不同的日志记录(pure virtual)
    };
    Transaction::Transaction() {
    	...
    	logTransaction();							// 最后动作是记录这笔账
    }
    
    class BuyTransaction: public Transaction {
    public:
    	virtual void logTransaction() const;
    	...
    }
    class SellTransaction: public Transaction {
    public:
    	virtual void logTransaction() const;
    	...
    }
    
    // 创建实例
    BuyTransaction b;
    

    创建实例b的时候,会调用构造函数,又因为BuyTransaction类继承了Transaction类,所以会先调用父类的构造函数,在父类的构造函数的最后一行又调用了一个虚函数。 因为还没有调用子类的构造函数,所以此虚函数会调用父类定义的函数,而不会调用子类的函数。这里也许就跟你想要的出现了偏差。

    规则二 令derived classes 将必要的构造信息向上传递至base class构造函数

    class Transaction {
    public:
    	explicit Transaction(const std::string& logInfo);
    	void logTransaction(const std::string& logInfo) const;   // 如今是个non-virtual函数
    };
    Transaction::Transaction(const std::string& logInfo) {
    	...
    	logTransaction(logInfo);
    }
    class BuyTransaction: public Transaction {
    public:
    	BuyTransaction( parameters )
    		: Transaction(createLogString( parameters ))      // 将log信息传给base class构造函数
    		{ ... }
    	...
    private:
    	static std:: string createLogString( parameters );
    }
    

    注意 这里子类的构造函数利用了初值列的方式向父类进行传递参数。

    总结

    1. 在构造函数和析构函数期间不要调用virtual函数,因为这类调用从不下降至derived class(比起当前执行构造函数和析构函数的那层)
  • 相关阅读:
    ROI选取
    大脑基底神经节
    毕业进度
    雅思8分大神叫你如何学习口语
    北京共有多少个区?_北京城中区是什么?城郊区是什么?
    功能连接分析中fisher-zsocre
    granger--platform_beta测试
    可买房摇号,北京市工作居住证全面解读
    2015年北京户口全攻略
    找实习
  • 原文地址:https://www.cnblogs.com/zhonghuasong/p/7354066.html
Copyright © 2020-2023  润新知