《深度探索c++ 对象模型》有感之构造函数和析构函数不能调用虚函数

5 篇文章 0 订阅

前言 

       在书上说,构造函数和析构函数不能调用需函数,但是有点不解,查了一下,后来终于明白了,主要原因是:

        我们知道,虚函数存在的价值是实现多态,为的是用父类的指针或者引用指向子类的对象,调用虚函数的时候,可以根据不同的子类对象调用不同版本的虚函数,可以说,虚函数就是为了多态而生的!!


1.好的如果按照使用者的角度来说:

构造函数的问题

         那么在构造函数中调用虚函数会出现什么问题呢,首先我们要知道,构造一个类的对象的时候,如过这个类是一个派生类,那么首先要调用父类的构造函数,先把父类的那部分构造出来,再调用子类的构造函数,把子类的这部分数据初始化,分配好内存,好了,如果父类的构造函数里面调用了虚函数,如果要实现多态的话,那么就是要调用子类版本的虚函数啦,但是,这个时候子类部分的成员变量还没开始分配内存初始化呢,调用子类版本虚函数的话,那么不就出问题了,要虚函数要访问子类成员变量肯定会去访问未知的内存,这就出大事儿了,首先按照使用者的想法,这种做法已经被推翻

析构函数的问题

        再说在析构函数中调用虚函数的问题,我们知道,析构函数的调用顺序和构造函数刚好相反,如果调用了父类的析构函数,那就证明子类构造函数已经调用了,子类对象的数据成员部分已经被释放,那么调用需函数的话,要访问子类版本的虚函数,那不可能啊,变量都释放了,你还要去访问这些变量,那么出问题了,所以按照使用者的想法,他的目的也没法达到。

所以,在这俩个函数中调用虚函数是不可能实现多态的,调用虚函数的意义就没有了,有些编译器会在编译的时候报错,有些不会报错,但执行的时候肯定报错那时候就麻烦了,可能你都不会知道错在哪里,所以错误越早发现越好,完毕

按照内存的角度说:

后记:以上其实在构造函数中调用虚函数在语意上是很危险的,因为那种想法很有可能出问题,但是实际上在内存的角度来说,它其实是安全的,因为虚函数的调用的通过vptr 来实现多态的,但是在C++的实现中,vptr的初始化,总是在构造函数调用之后,因此调用的虚函数的版本总是当前所在那个类的版本,虽然从内存的角度来说这是安全的,但是这已经失去了多态的性质,调用的意义就不大了,完全达不到使用者的目的,还不如直接显式这样调用:                          

class A

{

void virtual f(){}

A(){     A::f();   //这样显式的说明调用本类的那个虚函数     }

}

    因此,不推荐在构造函数和析构函数中使用虚函数


评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值