为什么构造函数内部不能调用虚函数

Posted mini-coconut

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么构造函数内部不能调用虚函数相关的知识,希望对你有一定的参考价值。

其实也不是不能调用,调用自然是可以的,只不过构造函数中的虚函数不具有多态性,不能达到我们想要的效果。

class Base
{
public:
    Base()
    {
        Fuction();
    }
 
    virtual void Fuction()
    {
        cout << "Base::Fuction" << endl;
    }
};
 
class A : public Base
{
public:
    A()
    {
        Fuction();
    }
 
    virtual void Fuction()
    {
        cout << "A::Fuction" << endl;
    }
};
 
// 这样定义一个A的对象,会输出什么?
A a;

我们一般想让它输出   A::Fuction    A::Fuction

但其实实际输出为      Base::Fuction    A::Fuction

给出的原因是说构造基类的时候,还未初始化派生类的成员变量。而网上很多说法说是虚表未建立。

具有虚函数的类的内存结构里除了非静态变量,还有一个虚指针,指向了虚表。  网上说的虚表未建立的说法是不合适的,因为同一个类的所有实例共享了同一张虚表。确切地说,是在基类的构造函数执行的时候,虚指针对应的内存里存放的是基类虚表的地址

c++ primer中明确指明,类的成员变量的初始化是完成在构造函数被调用后、构造函数函数体重的代码执行之前的。对于具有虚函数的类,虚指针也是在这个用户代码执行之前完成的。因此,执行基类的构造函数时,虚指针指向了基类的虚表;只有当执行派生类的构造函数时,虚指针的那一块内存单元的值又被修改为了派生类的虚表。

以上是关于为什么构造函数内部不能调用虚函数的主要内容,如果未能解决你的问题,请参考以下文章

C++ 构造函数不能是虚函数,基类析构函数应该为虚函数

为什么构造函数不能声明为虚函数,析构函数可以

什么函数不能是虚函数?为什么析构必须是虚函数?

什么函数不能是虚函数?为什么析构必须是虚函数?

C++类的构造函数不能为虚函数的原因

关于C++的虚函数在父类的内部调用