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

关于using声明结合虚继承的构造函数调用疑问

关于继承构造函数与虚基类初始化的问题

我在查阅cppreference中关于using声明的内容时,在“继承构造函数”章节看到如下代码:

struct V
{
    V() = default;
    V(int);
};
 
struct Q { Q() = default; };
 
struct A : virtual V, Q
{
    using V::V;
    A() = delete;
};
 
int bar() { return 42; }
 
struct B : A
{
    B() : A(bar()) {} // OK
};
 
struct C : B {};
 
int main()
{
    C c; // “bar” is not invoked, because the V subobject
         // is not initialized as part of B
         // (the V subobject is initialized as part of C,
         //  because “c” is the most derived object)
}

根据注释,由于C是最派生对象,V子对象由C初始化,因此bar()不会被调用。移除C的定义后代码变为:

struct V
{
    V() = default;
    V(int);
};
 
struct Q { Q() = default; };
 
struct A : virtual V, Q
{
    using V::V;
    A() = delete;
};
 
int bar() { return 42; }
 
struct B : A
{
    B() : A(bar()) {} // OK
};
 
int main()
{
    B b;
}

此时B是最派生对象,而A(int)构造函数是继承自V的虚基类构造函数,为什么bar()仍然不会被调用?


回答

核心原因是虚基类的初始化只能由最派生类全权负责,中间基类试图初始化虚基类的操作会被编译器直接忽略。

具体到这段代码里:

  • B作为最派生类,它的构造函数里写的: A(bar()),看似是调用A继承的V(int)构造函数,但这个继承的构造函数本质是用来初始化虚基类V的。
  • 按照C++规则,只有最派生类才有资格初始化虚基类,中间基类(这里的A)对虚基类的初始化请求会被跳过。所以B的构造函数没有显式初始化V时,编译器会自动调用V的默认构造函数V(),而A(bar())里的bar()根本不会被执行——因为编译器直接忽略了这个试图让A初始化虚基类的调用,连参数表达式都不会去求值。

简单说就是:继承的虚基类构造函数,只有最派生类调用它时才会触发虚基类的初始化;中间类调用的话,不仅不会初始化虚基类,连传入的参数表达式都不会执行。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 11:11:24