条款9:绝不在构造函数和析构函数中调用virtual 函数
来源:互联网 发布:大连pmp培训 知乎 编辑:程序博客网 时间:2024/05/21 11:26
条款9:绝不在构造函数和析构函数中调用virtual 函数
1、在构造函数中调用virtual 函数
先看段代码,书中的例子,修改了下
class Transaction{public:Transaction() {LogTransaction();}virtual void LogTransaction(){cout<<"Trasaction Log \n";}};class BuyTransaction : public Transaction{public:void LogTransaction() {cout<<"BuyTransaction Log \n";}};
调用
BuyTransaction b;结果
Trasaction Log
通过结果可以看出不是我们想要的。BuyTransaction b,这里BuyTransaction 构造函数会被调用,但会先调用基类Trasaction的构造函数,但该构造函数里面调用一个virtual 函数,意向是调用子类的LogTransaction函数,但实际上子类还没有开始构造,即对象还没有在内存中形成,对象的所有成员还没有定义,因此编译器不会让这样不可意料的事情发生,规定:base class构造期间virtual函数绝对不会下降到derived class型阶层,即在该阶段对象时隶属base class的,调用的virtual 函数不是virtual 函数。
在书中还有另一种说法,在derived class对象的base class构造期间,对象的类型是base class而不是derived class。不只virtual函数会被编译器解析至(resolve to)base class,若使用运行期类型信息,也会把对象视为base class类型。因为“derived 专属成分”尚未初始化,因此:对象在derived class构造函数开始执行前不会成为一个derived class对象。
2、在析构函数中调用virtual 函数
其结果和解释都可以跟上面一样,基类的析构函数中调用virtual 函数,结果还是调用基类的函数,因为析构函数的行为时:先调用子类的析构函数,再到基类,子类析构后,子类的所有成员均为未初始化,因此,进入基类的析构函数后对象就成为一个基类对象。
如何解决上面的问题呢?将virtual 函数修改为non-virtual 函数,在子类中构造函数中传入对应的值。
class Transaction{public:Transaction(const std::string &strLog) {LogTransaction(strLog);}void LogTransaction(const std::string &strLog){cout<<"Trasaction Log :"<<strLog<<endl;}};class BuyTransaction : public Transaction{public:BuyTransaction(const std::string &strLog) : Transaction(strLog){}};
记住
在构造和析构期间不要调用virtual函数,因为这类调用从不下降至derived class(比起当前执行构造和析构函数的那层)。
0 0
- 条款9:绝不在构造函数和析构函数中调用virtual 函数
- 条款9:绝不在构造和析构过程中调用virtual函数
- 条款9:绝不在构造和析构过程中调用virtual函数
- effective c++条款9(绝不在构造和析构过程中调用virtual函数)
- 条款9:绝不在构造和析构过程中调用virtual函数
- Effective C++ 条款9:绝不在构造和析构过程中调用virtual函数
- 【Effective_c++】条款09:绝不在构造和析构函数中调用virtual函数
- 条款09:绝不在构造和析构过程中调用virtual函数
- 条款09:绝不在构造和析构过程中调用virtual函数
- 条款09:绝不在构造和析构过程中调用virtual函数
- Effective C++:条款09:绝不在构造和析构过程中调用virtual函数
- Effective C++ 读书笔记 条款09:绝不在构造和析构过程中调用virtual函数
- 条款09 绝不在构造和析构过程中调用virtual函数
- 条款09:绝不在构造和析构过程中调用virtual函数
- 条款09 绝不在构造和析构过程中调用 virtual 函数
- 条款09:绝不在析构和构造过程中调用virtual函数
- 条款09:绝不在构造和析构过程中调用virtual 函数
- 《Effect C++》学习------条款09:绝不在构造和析构过程中调用virtual函数
- 黑马程序员_Java中的时间类
- ZOJ-2939
- android actionbar 不能显示overflow
- android:layout_weight属性详解
- neu之路
- 条款9:绝不在构造函数和析构函数中调用virtual 函数
- ASP.NET MVC 资料汇总
- 工作遇到的问题
- mybatis使用步骤
- 得到远程主机操作系统类型(只适用于发现NT5.2及以下系统)
- JUnit教程
- Linux utf8与gb2312转换函数
- 高次同余方程式的解数及解法
- 单调栈描述