绝不在构造和析构函数中调用 virtual 函数

看下面的这段代码,问 print调用的是基类还是派生类的版本?

答案是 基类。。。

可能大家会很惊讶,print不是virtual function 吗?为什么不是调用派生类的版本呢?

首先,当定义一个派生类的对象的时候,

由于 base class 构造函数的执行更早于 derived class构造函数,

所以当 base class constructor 调用的时候,派生类的成员尚未初始化(说明,这个时候真正的 虚函数表尚未完全初始化)。

如果这个时候调用 派生类的函数(可能使用未初始化的成员)的话,必定会出现麻烦。

因此 C++ 禁止你这样做。。

其实,在派生类对象的 base class 构造期间, 对象的类型是 bass class 而不是 derived class.

因此,虚函数调用的一定是 基类的版本。。

相同的道理,同样适用于析构函数。

大家知道,派生类对象析构的时候,析构函数调用顺序正好与 构造函数相反:

派生类的析构函数先于基类的析构函数。

因此,在 base 析构函数调用的过程中, 编译器视其为基类对象。。

绝不在构造和析构函数中调用 virtual 函数

时间: 2024-11-18 13:31:50

绝不在构造和析构函数中调用 virtual 函数的相关文章

Effective C++ Item 09-绝不在构造函数和析构函数中调用virtual函数

Item 09-绝不在构造函数和析构函数中调用virtual函数(Never call virtual functions during construction or destruction) Why? 由于base class构造函数的执行更早于derived class构造函数,当base class构造函数执行derived class的成员变量尚未初始化.如果期间调用的virtual函数下降至derived class阶层,要知道derived class的函数几乎必然取用local成

EC笔记,第二部分:9.不在构造、析构函数中调用虚函数

9.不在构造.析构函数中调用虚函数 1.在构造函数和析构函数中调用虚函数会产生什么结果呢? #include <iostream> using namespace std; class cls1{ public: cls1(){ newMake(); }; ~cls1(){ deleteIt(); }; virtual void newMake(){ cout<<"cls1 make"<<endl; } virtual void deleteIt()

条款9:绝不要在构造以及析构函数中调用虚函数

在构造以及析构函数期间不要调用virtual函数,因为这类调用从不下降到derived class中.例如说下面这个例子: 1 class Transaction{ 2 public: 3 Transaction(); 4 virtual void logTransactions()s const = 0; 5 //... 6 }; 7 Transaction::Transaction() 8 { 9 //... 10 logTransaction(); 11 } 12 class BuyTra

C++ 笔记(二) —— 不要在构造和析构函数中调用虚函数

ilocker:关注 Android 安全(新手) QQ: 2597294287 1 class Transaction { //所有交易的 base class 2 public: 3 Transaction(); 4 virtual void logTransaction() const = 0; //做出一份因类型不同而不同的日志记录 5 … 6 } 7 Transaction::Transaction() { 8 … 9 logTransaction(); 10 } derived cl

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

  1.当在一个子类当中调用构造函数,其父类构造函数肯定先被调用.如果此时父类构造函数中有一个virtual函数,子类当中也有,肯定执行父类当中的virtual函数,而此时子类当中的成员变量并未被初始化,所以无法调用子类与之对应的函数.即为指向虚函数表的指针vptr没被初始化又怎么去调用派生类的virtual函数呢?析构函数也相同,派生类先于基类被析构,又如何去找派生类相应的虚函数? 2.做法:将子类的某个函数改为non-virtual,然后在子类构造函数中传递参数给父类函数.然后父类的构造函数

Effective C++ Item 9 绝不在构造和析构过程中调用virtual函数

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:在构造和析构期间不要调用virtual函数,因为这类调用从不下降至derived class(比起当前执行构造函数和析构函数的那层) 示例: <pre name="code" class="cpp">#include <iostream> #include <string> using namespace std; c

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

(整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 为方便采用书上的例子,先提出问题,在说解决方案. 1 问题 1: class Transaction{ 2: public: 3: Transaction(); 4: virtual void LogTransaction() const = 0 ; 5: ... 6: }; 7:  8: Transaction::Transaction() //Base cl

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

在构造函数中调用virtual函数时,base class构造期间virtual函数是不会下降到derived class层 如: class Transaction{ public: Transaction(); virtual void logTransaction() const = 0; }; Transaction::Transaction() { logTransaction(); } class BuyTransaction: public Transaction{ public:

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

看过C++对象模型的话就可以知道,在构造基类时,完整的vtable没有建立起来(表项没有被相应的子类函数替换),因而无法调用到子类的函数(即构造函数中的virtual函数是本类里的方法,不是virtual的).书中也说即使调用了,因为构造函数的调用顺序,父类在构造时子类的成员还没有初始化可能,此时调用virtual函数无疑会造成混乱. 类似的关于析构过程,是一个子类先执行然后再父类执行的过程,如果在父类中调用virtual函数那么可能涉及到的子类数据已经被释放或者重置了,应该是出于这个考虑吧.