C++ new T / new T() / new T(args) 完整区别
·
C++ new T / new T() / new T(args) 完整区别
只讨论普通 new 表达式,不牵扯 operator new、placement new,聚焦「括号有无」带来的初始化差异。
一、核心区分规则
new T:默认初始化,内置类型随机脏值,自定义类走默认构造new T():值初始化,内置类型清零,自定义类调用无参构造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.0new bool()→ falsenew 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) |
一句话记忆重点
- 内置类型、无构造结构体:有无括号差别巨大
- 不带
():内存不清洗,随机垃圾; - 带
():强制清零、值初始化。
- 不带
- 有自定义无参构造的类:
new T和new T()效果一模一样,无区别。 new T(数值)是单独传参构造,和前两者不属于同一对比维度。
更多推荐

所有评论(0)