EC笔记,第二部分:9.不在构造、析构函数中调用虚函数
9.不在构造、析构函数中调用虚函数
1.在构造函数和析构函数中调用虚函数会产生什么结果呢?
#;
}
上述程序会产生什么样的输出呢?
你一定会以为会输出:
cls2 make
cls2 delete
或者是:
cls2 make
cls2 make
cls2 delete
cls2 delete
(如果你想到了后一种,说明你对派生类的构造有一定了解)
因为在构造和析构函数使用了虚函数,应该是迟绑定。但是实际的输出是:
cls1 make
cls2 make
cls2 delete
cls1 delete
为什么呢?
理由如下:
在程序构造一个cls2对象的时候,会调用基类(也就是cls1)的构造函数,但是这时cls2还没有被构造,所以虚表中只有cls1的newMake函数,所以程序只能调用cls1的newMake,然后到cls2的构造函数体执行,这时cls2已经被构造,所以cls2的构造函数会调用cls2的newMake
析构的时候,cls2的部分会率先释放,等到cls1释放的时候,虚表中已经不存在deleteIt的cls2版本了
2.解决方案
不在构造函数中调用虚函数,而是写一个通用的构造函数(或者通用的非构造函数,在基类构造函数中调用)
EC笔记,第二部分:9.不在构造、析构函数中调用虚函数的更多相关文章
- C++箴言:避免构造或析构函数中调用虚函数
如果你已经从另外一种语言如C#或者Java转向了C++,你会觉得,避免在类的构造函数或者析构函数中调用虚函数这一原则有点违背直觉.但是在C++中,违反这个原则会给你带来难以预料的后果和无尽的烦恼. 正 ...
- C++构造与析构函数中调用虚函数的问题
前些天想把以前写的内存池算法重写一遍,跨平台是第一目标,当时突发奇想,因为不愿意做成一大堆#if..#end,所以想利用C++的多态性,但是怎么让内存池完好退出却没想到自认为完美的方案.但是一个很偶然 ...
- 读书笔记 effective c++ Item 9 绝不要在构造函数或者析构函数中调用虚函数
关于构造函数的一个违反直觉的行为 我会以重复标题开始:你不应该在构造或者析构的过程中调用虚函数,因为这些调用的结果会和你想的不一样.如果你同时是一个java或者c#程序员,那么请着重注意这个条款,因为 ...
- C++ 笔记(二) —— 不要在构造和析构函数中调用虚函数
ilocker:关注 Android 安全(新手) QQ: 2597294287 class Transaction { //所有交易的 base class public: Transaction( ...
- C++-不要在构造和析构函数中调用虚函数
在实习的单位搞CxImage库时不知为什么在Debug时没有问题,但是Release版里竟然跳出个Pure virtual function call error! 啥东西呀,竟然遇上了,就探个究竟吧 ...
- 09——绝不在构造和析构函数中调用virtual函数
在base class构造期间,virtual函数不是virtual函数. 构造函数.析构函数中不要调用virtual函数.
- 绝不在构造和析构函数中调用 virtual 函数
看下面的这段代码,问 print调用的是基类还是派生类的版本? 答案是 基类... 可能大家会很惊讶,print不是virtual function 吗?为什么不是调用派生类的版本呢? 首先,当定义一 ...
- 条款9:不要在构造和析构过程中调用virtual函数
如下是一个股票交易的例子: class Transaction // 交易的基类 { public: Transaction(); ; // 用于记录交易日志 }; Transaction::Tran ...
- Effective C++ .09 不在构造和析构过程中调用virtual函数
看过C++对象模型的话就可以知道,在构造基类时,完整的vtable没有建立起来(表项没有被相应的子类函数替换),因而无法调用到子类的函数(即构造函数中的virtual函数是本类里的方法,不是virtu ...
随机推荐
- [.net 面向对象程序设计进阶] (20) 反射(Reflection)(上)利用反射技术实现动态编程
[.net 面向对象程序设计进阶] (20) 反射(Reflection)(上)利用反射技术实现动态编程 本节导读:本节主要介绍什么是.NET反射特性,.NET反射能为我们做些什么,最后介绍几种常用的 ...
- 启用WebApi 2里的Api描述信息(Help下的Description)
环境:vs2013+web api 2 问题:默认情况下新建的Web Api 2项目,自带的Help页下会显示Api的相关信息,但Description那一栏无法获取到数据,如下图所示: 解决: 1. ...
- Can't use Subversion command line client: svn Probably the path to Subversion executable is wrong. Fix it.
1.最近使用SVN工具时,Checkout出项目到本地后后,然后将其导入到Intellij idea中开发,在提交svn代码的时候,出现这样的错误:Can't use Subversion comma ...
- Objective-C 原型模式 -- 简单介绍和使用
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. Prototype原型模式是一种创建型设计模式,Prototype模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建 ...
- 探讨Js的事件的冒泡阶段
近来看到了一个新的知识点叫Js的事件冒泡,因此决定自己来研究一番. 大家应该都知道,Js中的事件处理分为三个阶段,1:事件的捕获阶段,2:处于目标阶段,3:事件的冒泡阶段.那么什么是事件的捕获和冒泡呢 ...
- HTML5_02之视频、音频、Canvas
1.HTML5新特性之视频播放--video: ①例:<video src=""></video> ②video标签默认为300*150的inline-bl ...
- java轻量级IOC框架Guice
Google-Guice入门介绍(较为清晰的说明了流程):http://blog.csdn.net/derekjiang/article/details/7231490 使用Guice,需要添加第三方 ...
- SSIS Design1: 源数据提取
数据量的大小由两个方面决定:行的宽度和数据行的数量,为了减少ETL运行的时间,可以从源数据的提取上做优化,从数据源的输入上控制数据的质量和大小,减少转换和IO. 一,减少行的宽度 1,只加载需要的数据 ...
- C#设计模式系列:原型模式(Prototype)
1.原型模式简介 1.1>.定义 原型模式(Prototype)用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象. 1.2>.使用频率 中 1.3>.原型模式应用 首先 ...
- Spire.DOC生成表格测试
首先,很感谢Jack对我的信任,让我来写一个评测,在此对Jack说一声抱歉,由于本人愚钝,并且最近项目比较紧张,把评测这个事情脱了一个月之久,由于往后的日子可能更忙,所以今晚抽空只能只写了一个小程序来 ...