C++运行时多态(虚函数)语义失效的场景

在基类的构造函数中调用虚函数

在构造函数中调用虚函数,只会得到无多态的效果,也即调用基类中的那个虚函数的实现,而非派生类中的。直观的想,基类构造时,派生类还没有构造,所以派生类的虚函数中的this指针还没法用,所以就不行啦~

在基类析构函数中调用虚函数

因为析构函数的执行顺序和析构函数相反,先执行派生类的析构函数,再执行基类的析构函数。所以基类的析构函数执行时,派生类已经析构过了,所以这时候也只能得到无多态的效果,无法调用派生类的虚函数实现,如果能调用的话,派生类已经被销毁了,成员都无效了,只会crash

虚函数表什么时候生成

可以把虚表看作是模块的全局数据或者静态数据

为什么构造函数不能是虚函数

从使用角度来看

虚函数的作用是在实例的类型信息不全的情况下,也可以得到对应的调用。但是构造函数本身就是初始化实例用的。

从实现角度来看

每个构造函数调用的时候,编译器都会把实例的vptr指向相应类型的vtbl,这是用来实现运行时多态用的。此时vptr指向的是当前类型的vtbl,不是基类的,也不是派生类的(因为不知道谁继承了它),在接下来的派生类构造中(继承层次>1的情况),每次构造新派生类的时候,又会把当前实例的vptr再重置为最新派生类类型的vtbl,直到最后的构造函数结束。

将构造函数声明为virtual的意图无非是想通过基类的类型信息来创建子类(其实可以用原型模式代替)但是在构造函数执行时,此时的构造函数并不知道自己的派生类的构造函数长什么样(或者有没有),所以在C++这样的构造顺序的情况下,把他实现为virtual并没有意义,因为拿不到派生类的信息。

posted @ 2020-09-02 21:03  joeyzzz  阅读(637)  评论(0编辑  收藏  举报