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

为什么C++中default声明的构造函数会对类成员执行零初始化?

问题复现

测试代码如下:

#include <iostream>

struct A {
    int x;

    A() {};
};

struct B {
    int x;

    B() = default;
};

int main() {
    int x = 5;
    x = 7;

    printf("before: %d\n", x);

    new(&x) A();
    printf("%d\n", x);

    new(&x) B();
    printf("%d\n", x);
}

运行输出结果:

before: 7
7
0
核心原因

这个差异是C++标准对不同类型默认构造函数和值初始化规则的明确规定导致的,核心区别在于两个类的默认构造函数是否属于「用户提供」的范畴:

  • 类A的A() {}是用户手动实现的空构造函数,属于用户提供的默认构造函数
  • 类B的B() = default是显式要求编译器生成默认构造,类内声明的=default默认构造不属于用户提供的默认构造函数

结合值初始化规则就能解释执行结果:
你用placement new构造对象时用的是A()和B()的写法,这属于C++的值初始化场景,规则如下:

  1. 当值初始化的类类型拥有「用户提供的默认构造函数」时,直接调用该构造函数,不会做额外处理:
    类A的空构造函数没有对x做任何赋值操作,所以x保留了原本内存里的值7,第一次输出为7。
  2. 当值初始化的类类型拥有「非用户提供的默认构造函数」时,会先把整个对象的内存区域做零初始化,再调用默认构造函数:
    类B的默认构造是编译器生成的空实现,零初始化步骤会把x对应的内存置为0,调用构造函数也没有修改x的值,所以第二次输出为0。

补充说明:如果你用的是默认初始化写法(比如new(&x) B不带括号),不会触发零初始化步骤,x会保留原来的7,不会被置零。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 11:36:03