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

为何基类构造函数可通过花括号调用却无法通过圆括号调用?

继承类构造函数调用差异的原因解析

先看示例代码:

struct Base {
  Base(int x) : x_{x} {}

  int get() { return x_; }

private:
  int x_ = 0;
};

struct Derived : Base {};

int main() {
  Derived d{5}; // Works fine
  std::cout << d.get() << std::endl;

  Derived dd(5); // Won't work
  std::cout << dd.get() << std::endl;
}

核心原因拆解

  • 列表初始化(花括号{})的标准规则
    Derived属于C++标准定义的聚合类型:没有用户声明的构造函数、没有私有/保护的非静态数据成员、没有虚函数、没有基类构造函数的继承声明等。对于聚合类型的列表初始化,标准允许直接将初始化参数传递给基类的构造函数,完成基类部分的初始化,因此Derived d{5};可以正常编译。

  • 直接初始化(圆括号())的标准规则
    直接初始化不会触发聚合类型的特殊初始化逻辑。由于Derived没有显式通过using Base::Base;引入基类的构造函数,编译器无法找到接受int参数的Derived构造函数,因此Derived dd(5);在符合标准的编译器(如GCC、Clang)中会报错。

  • MSVC的非标准扩展
    MSVC默认开启了一项非标准的编译器扩展,允许在直接初始化聚合派生类时,隐式将参数传递给基类的构造函数,这相当于绕过了标准中对直接初始化的限制,所以这段代码在MSVC中可以正常运行,但这并不是C++标准的规定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 11:17:11