You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++抽象类构造函数调用疑问:派生类指针场景下的机制解析

抽象类构造函数调用逻辑解析

咱们把问题拆成两部分来聊,其实逻辑很清晰:

一、为什么抽象类的构造函数会被调用?

这是C++继承机制的硬性规则——只要你创建派生类对象,不管是用派生类指针还是直接声明对象,派生类的构造函数都会自动先调用它所有基类(包括抽象基类)的构造函数。

为啥要这么做?因为派生类对象里包含了基类的「子对象」(也就是基类定义的成员变量等内容),必须先把基类的部分初始化到位,才能接着初始化派生类自己的成员。哪怕基类是抽象类,这个初始化流程也不能跳过——抽象类只是不能被直接实例化,但它的成员依然需要被正确初始化,毕竟派生类继承了这些成员嘛。

就拿你给的代码来说,当执行new inherit()的时候,编译器会先调用pure_virtual的构造函数,把基类子对象初始化完毕,再调用inherit的构造函数处理派生类自己的部分。

二、会不会创建抽象类实例来存储虚表?

绝对不会!抽象类的核心特性就是不能被实例化,C++编译器会直接禁止你尝试创建抽象类的对象,这点完全不用担心。

那虚表(vtable)是怎么回事?其实虚表是属于类的,不是属于某个对象实例的。当编译器遇到带有虚函数的类(包括抽象类)时,会在编译阶段就为这个类生成对应的虚表,存在程序的只读数据段里。派生类会继承基类的虚表,然后把自己实现的虚函数(包括纯虚函数的实现)覆盖到虚表对应的位置。

每个对象里只会存一个虚表指针(vptr),这个指针会在构造函数执行的时候被设置,指向当前类的虚表。根本不需要创建抽象类的实例来存虚表——虚表从一开始就是类级别的全局资源。

补全代码后的运行示例

把你的代码补全后运行:

#include <iostream>
using namespace std;

class pure_virtual {
public:
    pure_virtual() {
        cout << "Virtual class constructor called !" << endl;
    }
    virtual void show()=0;
};

class inherit: public pure_virtual {
public:
    inherit() {
        cout << "Derived class constructor called !" << endl;
    }
    void show() override {
        cout << "Derived show function" << endl;
    }
};

int main() {
    pure_virtual* ptr = new inherit();
    ptr->show();
    delete ptr;
    return 0;
}

输出结果会是:

Virtual class constructor called !
Derived class constructor called !
Derived show function

完全符合咱们刚才说的逻辑:先初始化基类子对象,再初始化派生类,最后调用派生类的虚函数。

内容的提问来源于stack exchange,提问作者SGoodman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:54:12