• 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(比起当前执行构造函数和析构函数的那层)
  • 相关阅读:
    对网页图片的增删改管理
    还没搞完的排序(后期更新)
    web实现图片动态
    C++11 笔记
    如何解决刷新系统桌面响应速度很慢的问题
    CGrowableArray解析 _ DXUT容器
    测试...外部指针访问private
    CustomUI Direct3D9_Sample
    缺少.lib文件导致的Link2019 解决方案汇总
    在DirectX9中使用DXUT定制按钮来控制模型旋转的问题
  • 原文地址:https://www.cnblogs.com/zhonghuasong/p/7354066.html
Copyright © 2020-2023  润新知