不该在构造函数和析构函数期间调用virtual函数,这一点是C++与jave/C#不同的地方之一。

假设有一个class继承体系,用来模拟股市交易如买进、卖出的订单等等。这样的交易一定要经过审计,所以每当创建一个交易对象,在审计日志中也需要创建一笔适当记录。

正确的做法是在基类Transaction内将logTransaction函数改为non-virtual,然后要求派生类构造函数传递必要信息给基类Transaction的构造函数,这样那个构造函数便可安全地调用non-virtual logTransaction。正确用法如下:

class Transaction
{
public:
Transaction();
~Transaction(); explicit Transaction(const string& logInfo);
void logTransaction(const string& logInfo) const; //non-virtual函数 private: }; Transaction::Transaction(const string& logInfo)
{
...
logTransaction(logInfo); //非non-virtual调用
}

 

class BuyTransaction : public Transaction
{
public:
BuyTransaction(parameters) : Transaction(createlogString(parameters)) //将日志信息传递给基类构造函数
{
...
}
...
~BuyTransaction(); private:
static string createlogString(parameters);
};

  注意示例BuyTransaction内的private static函数 createlogString的运用。比起在成员初值列内给予基类所需的数据,利用辅助函数创建一个值传递给基类的构造函数往往比较方便(也比较可读)。令此函数为static,也就不可能意外指向“初期未成熟的BuyTransaction对象内尚未初始化的成员变量”。这很重要,正是因为“那些成员变量处于未定义状态”,所以在基类构造和析构期间调用的virtual函数不可下降至派生类。

请牢记:

 在构造和析构期间不要调用virtual函数,因为这类调用从不下降至派生类(比起当前执行构造函数和析构函数的那层)。

条款09:绝不在构造和析构过程中调用virtual函数的更多相关文章

  1. Effective C++_笔记_条款09_绝不在构造和析构过程中调用virtual函数

    (整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 为方便采用书上的例子,先提出问题,在说解决方案. 1 问题 1: ...

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

    在构造和析构期间不要调用virtual函数,因为这类调用从不下降至derived class(比起当前执行构造函数和析构函数的那层).

  3. Effective C++ 条款九、十 绝不在构造和析构过程中调用virtual函数|令operator=返回一个reference to *this

      1.当在一个子类当中调用构造函数,其父类构造函数肯定先被调用.如果此时父类构造函数中有一个virtual函数,子类当中也有,肯定执行父类当中的virtual函数,而此时子类当中的成员变量并未被初始 ...

  4. 条款9:绝不在构造和析构过程中调用virtual函数(Never call virtual functions during construction or destruction)

    NOTE:在构造和析构期间不要调用virtual函数,因为这类调用从不下降至derived class(比起当前执行构造函数和析构函数的那层)

  5. Effective C++ .09 不在构造和析构过程中调用virtual函数

    看过C++对象模型的话就可以知道,在构造基类时,完整的vtable没有建立起来(表项没有被相应的子类函数替换),因而无法调用到子类的函数(即构造函数中的virtual函数是本类里的方法,不是virtu ...

  6. NO.8:绝不在构造或者析构过程中调用virtual函数

    在构造和析构执行期间不要调用virtual函数,因为这类调用从不会下降至derived class(比起当前执行构造函数和析构函数) 如果在base class 构造函数或者析构函数调用virtual ...

  7. 【09】绝不在构造和析构过程中调用virtual方法

    1.绝不在构造和析构过程中调用virtual方法,为啥? 原因很简单,对于前者,这种情况下,子类专有成分还没有构造,对于后者,子类专有成分已经销毁,因此调用的并不是子类重写的方法,这不是程序员所期望的 ...

  8. 条款9:不要在构造和析构过程中调用virtual函数

    如下是一个股票交易的例子: class Transaction // 交易的基类 { public: Transaction(); ; // 用于记录交易日志 }; Transaction::Tran ...

  9. 绝不要在构造函数和析构过程中调用virtual函数

    下面是一个用来塑模股市交易的类: derived的类的构造函数被调用,但是首先得调用基类Transaction的构造函数,但是在后面还得调用virrual函数,这个时候子类的对象的构造还没有完成,那么 ...

随机推荐

  1. 跟我学CMD实战系列之二 ——数据压缩备份

    需求:每天下班时,将本地硬盘上的projects目录压缩为rar文件,文件名中必须含有当天日期信息,例如projects_20070902.rar. 分析:1. 压缩可以调用WinRAR的命令行版本r ...

  2. Excel创button宏调用

    今天,匆匆写了一个宏,但发现已被用来创建button开发工具菜单不见了. 在十分钟找Excel转了个遍,终究Excel通常使用在中的选项,首先Mark下一个,离开同样找不到鞋. 几个截面图.促进突然, ...

  3. Arcgis api for javascript学习笔记(3.2X版本)-初步尝试

    Arcgis api for javascript(3.22版本)官方地址 :https://developers.arcgis.com/javascript/3/ 1. 根据官方示例实现一个简单地图 ...

  4. 关闭Wind XP/Vista/Win7的DEP数据执行保护汇总(转)

    数据执行保护 (DEP) 是一种Windows安全机制,从Windows版本顺序上看是从Windows XP SP2开始引入,通过监视程序以确保它们使用的系统内存是安全的,帮助防止操作系统受到病毒和其 ...

  5. vs2008C1902数据库管理程序不匹配

    打开一大早vs2008,有这么奇怪的错误, 删了dll正好.图. 版权声明:本文博主原创文章.博客,未经同意不得转载.

  6. Netty源代码学习——EventLoopGroup原理:NioEventLoopGroup分析

    类结构图: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd29ya2luZ19icmFpbg==/font/5a6L5L2T/fontsize/400/f ...

  7. thread、Task、async & await

    学习 Jesse 的文章 async & await 的前世今生(Updated) 而来 Thread是最开始使用的多线程.new一个Thread对象,将方法传进去.手动Start() 还可以 ...

  8. WPF 窗体中获取键盘和鼠标无操作时的超时提示

    原文:WPF 窗体中获取键盘和鼠标无操作时的超时提示 通过调用Windows API中的GetLastInputInfo来获取最后一次输入的时间 , , );            timer.Tic ...

  9. WPF中StringFormat的用法

    原文:WPF中StringFormat的用法 WPF中StringFormat的用法可以参照C#中string.Format的用法 1. C#中用法: 格式化货币(跟系统的环境有关,中文系统默认格式化 ...

  10. doker基础

    去 Docker Hub 上拉取一个叫 hello-world 的集装箱docker pull hello-world然后让这个集装箱跑起来docker run hello-world查看本机所安装的 ...