C++ new T / new T() / new T(args) 完整区别

只讨论普通 new 表达式,不牵扯 operator new、placement new,聚焦「括号有无」带来的初始化差异。

一、核心区分规则

  1. new T默认初始化,内置类型随机脏值,自定义类走默认构造
  2. new T()值初始化,内置类型清零,自定义类调用无参构造
  3. new T(xxx)参数初始化,传入参数匹配对应构造函数

1. 内置基础类型(int /float/char /bool/ 指针等)

new int

只分配堆内存,不做任何清零,内存保留原有随机垃圾值

cpp

运行

int* p1 = new int;
cout << *p1; // 随机乱码数字,未初始化

new int()

分配内存后值初始化,强制置 0

cpp

运行

int* p2 = new int();
cout << *p2; // 固定输出 0

其他内置同理:

  • new double() → 0.0
  • new bool() → false
  • new char() → '\0'
  • new int*() → nullptr

new int(10)

带参数,直接初始化为指定值

cpp

运行

int* p3 = new int(10);
cout << *p3; // 10

2. 自定义类 / 结构体

分两种情况:有无自定义无参构造函数

cpp

运行

struct Test {
    int a;
    // 无参构造
    Test() : a(100) {}
    // 有参构造
    Test(int v) : a(v) {}
};

new Test

调用无参构造函数,等价 new Test()

cpp

运行

Test* t1 = new Test;
cout << t1->a; // 100

new Test()

同样调用无参构造,和上面效果完全一致

cpp

运行

Test* t2 = new Test();
cout << t2->a; // 100

new Test(50)

匹配有参构造,传入参数初始化

cpp

运行

Test* t3 = new Test(50);
cout << t3->a; // 50

特殊场景:类没有自定义构造(只有成员,编译器合成默认构造)

cpp

运行

struct Data {
    int x;
};
  • new Data:x 随机脏值(默认初始化)
  • new Data():x 自动置 0(值初始化)

3. 数组 new [] 的括号区别(延伸高频考点)

new int[5]

数组元素全部默认初始化,int 全随机脏值

cpp

运行

int* arr1 = new int[5];
// arr1[0]~arr1[4] 都是随机垃圾

new int[5]()

数组整体值初始化,所有元素置 0

cpp

运行

int* arr2 = new int[5]();
// 全部为 0

new int[5]{1,2} C++11 列表初始化

前两个赋值,剩余自动补 0,和括号逻辑不同。


4. 表格汇总对比

表格

写法 初始化类型 内置类型 (int) 无自定义构造类 Data {int x} 有无参构造 Test
new int 默认初始化 随机脏值 - -
new int() 值初始化 固定 0 - -
new Data 默认初始化 - x 随机脏值 -
new Data() 值初始化 - x=0 -
new Test 默认初始化 - - 调用 Test () 构造
new Test() 值初始化 - - 调用 Test () 构造
new int(66) 参数初始化 *p=66 - -
new Test(99) 参数初始化 - - 调用 Test (int)

一句话记忆重点

  1. 内置类型、无构造结构体:有无括号差别巨大
    • 不带():内存不清洗,随机垃圾;
    • ():强制清零、值初始化。
  2. 有自定义无参构造的类new Tnew T() 效果一模一样,无区别。
  3. new T(数值) 是单独传参构造,和前两者不属于同一对比维度。

更多推荐