[C++] new带括号和不带括号

本文详细解析了在C++中使用new操作符时,在对象名前加括号与不加括号的区别。主要涉及自定义类类型与内置类型的行为差异,强调了不带括号的new可能导致的问题,并通过实例说明了正确使用new的重要性。

在new对象的时候有加上(),有不加(),不知道这个到底是什么区别?
比如:
CBase *base = new CDerived();
CBase *base = new CDeviced;

 

很多人都说,加括号调用没有参数的构造函数,不加括号调用默认构造函数或唯一的构造函数。这是有问题的。

对于自定义类类型:

       如果该类没有定义构造函数(由编译器合成默认构造函数)也没有虚函数,那么class c = new class;将不调用合成的默认构造函数,而class c = new class();则会调用默认构造函数。

       如果该类没有定义构造函数(由编译器合成默认构造函数)但有虚函数,那么class c = new class;和class c = new class();一样,都会调用默认构造函数。

       如果该类定义了默认构造函数,那么class c = new class;和class c = new class();一样,都会调用默认构造函数。

 

对于内置类型:

       int *a = new int;不会将申请到的int空间初始化,而int *a = new int();则会将申请到的int空间初始化为0

 以下两个语句的区别是:第一个动态申请的空间里面的值是随机值,第二个进行了初始化,里面的值为0:

  1. int *p1 = new int[10];  
  2. int *p2 = new int[10]();  

结论:别使用不带括号的new。

class A{
public:
//A(){a=1;}
public:
int a;
};

A *a1=new A;
A *a2=new A();

cout<<a1->a<<endl; //输出:-842150451

cout<<a2->a<<endl; //输出0

A a3;
cout<<a3.a<<endl; //运行异常,a没有初始化。

如果加上一个virtual,如virtual ~A(){},

cout<<a1->a<<endl; //输出:-842150451

cout<<a2->a<<endl; //输出 -842150451

-------------下面是网上找的帖子,对理解上面的现象可能会有帮助-------------------

一个类满足下列其中任何一个条件:
1.包含了一个类的对象,这个对象有一个构造函数(包括编译器合成的默认构造函数)
2.如果继承自一些基类,其中某些基类有一个构造函数(包括编译器合成的默认构造函数)
3.有一个虚函数,或者继承到了虚函数
4.有虚基类

如果这个类没有默认的构造函数,编译器就会合成一个默认的构造函数,分别做以下事情
如果这个类有构造函数,编译器就会扩张所有构造函数,做以下事情
1.调用这个对象的构造函数
2.调用基类的构造函数
3.设置正确的虚函数表指针
4.设置指向虚基类对象的指针

去读下《深入理解c++对象模型》,那里面解释的很清楚

<think>首先,用户的问题是基于提供的引用内容:用户想了解在C++中使用new node()时括号内应该填写什么内容。具体来说,用户问的是“C++new node()括号内的内容”。 从引用中,我可以提取相关信息: - 引用[1]讨论了Node-API,但这似乎与用户的问题无关,因为它涉及Node.js的原生模块开发。 - 引用[2]提到C++内存管理,特别是newdelete。它说:“C++98支持初始化new的数组,但C++11可以大括号初始化,普通数组一样。”并给出了例子:`int* p4 = new int[5]; int* p4 = new int[5]{1,2};`。这表明new操作符可以用于动态分配数组,并在C++11中支持初始化列表。 - 引用[3]是关于Node.js调用C++的,提到了Add方法About方法,但直接与new node()相关。 - 引用[4]直接讨论了C++new对象后不加括号的问题:`BNode * p = new BNode; BNode * p2 = new BNode();`。用户的问题是针对这个的:在new node()中括号内应该填写什么。 用户的问题焦点是`new node()`中的括号内容。在C++中,`new`操作符用于动态分配内存并调用构造函数。括号内的内容对应于构造函数的参数。 回顾引用[4],它显示了两种方式:`new BNode``new BNode()`。前者调用默认构造函数(如果有),后者也调用默认构造函数,但可能有同的初始化行为,尤其是在旧版本的C++中。 关键点: - 在C++中,当使用`new ClassName()`时,括号内传递的是构造函数所需的参数。 - 如果类`node`有一个默认构造函数(无参数),那么括号内可以是空的:`new node()`。 - 如果类有参数化的构造函数,你需要提供相应的参数,例如`new node(arg1, arg2)`。 用户的问题是基于引用[4],其中提到了`BNode * p = new BNode;``BNode * p2 = new BNode();`。用户问的是在`new node()`中括号内应该填写什么内容。这里的`node`可能是一个自定义类或结构体。 在引用[4]的上下文中,`BNode`是一个结构体: ```c++ typedef struct BNode { int data; struct BNode * Lson; struct BNode * Rson; } BNode, *Bptr; ``` 那么,在`new BNode()`中,括号内没有内容,因为结构体可能有默认构造函数(如果是POD类型),或者编译器生成的构造函数。 在C++中,对于类类型: - `new T` `new T()` 在行为上有所同,特别是在初始化上。 - `new T`: 执行默认初始化。对于内置类型(如int),初始化;对于类类型,调用默认构造函数。 - `new T()`: 执行值初始化。对于内置类型,初始化为0;对于类类型,调用默认构造函数。 但在现代C++C++11及以后),差异较小,因为值初始化更一致。 至于括号内的内容,它取决于类的构造函数。例如: - 如果类`node`有一个无参数构造函数,`new node()`是合法的。 - 如果有参数,如`node(int value)`,则需要参数:`new node(10)`。 用户的问题是“括号内应该填写什么内容”,所以我需要解释这取决于构造函数。 根据系统级指令: - 所有行内数学表达式使用`$...$`格式。 - 独立公式使用`$$...$$`。 - 使用中文回答。 - 生成相关问题。 - 引用后添引用标识。 我的回答应该结构化: 1. **清晰解释问题**:基于C++知识。 2. **参考引用**:尤其是引用[2][4],因为它们最相关。 3. **生成相关问题**:在末尾。 步骤的回答结构: - 先介绍在C++中使用`new`操作符的基本概念。 - 解释`new node()`中括号的作用。 - 讨论括号内内容的规则。 - 提供例子。 - 基于引用添注释。 最后,生成相关问题。 中文回答。 关键点总结: - `new node()` 调用类的构造函数。 - 括号内传递构造函数的参数。 - 如果无参数,可以空着或省略括号(但在某些情况下有区别)。 - 在引用[4]的例子中,`new BNode()` 可能用于确保值初始化。 在引用[4]中,用户问是否括号,这涉及初始化差异。 对于用户的具体问题:“括号内应该填写什么内容”,答案是:取决于`node`类的构造函数参数。 答案框架: 1. **解释概念**:在C++中,`new`操作符用于动态内存分配。`new node()` 创建一个`node`对象,并调用其构造函数。括号内的内容是与构造函数参数匹配的值。 2. **没有参数的情况**:如果`node`有一个默认构造函数(无参数),则括号内可以为空:`new node()`。 3. **有参数的情况**:如果构造函数需要参数,例如`node(int id)`,则需要提供:`new node(42)`。 4. **初始化差异**:参考引用[4],`new node` `new node()` 在初始化行为上可能同,特别是在旧C++标准中。`new node()` 确保值初始化。 5. **数组情况**:参考引用[2],对于数组,可以使用初始化列表:`new int[5]{1,2,3}`,但这是直接相关,除非`node`是数组。 6. **建议**:建议查看`node`类的定义以确定所需参数。 生成相关问题: - 在C++中,new操作符的底层原理是什么? - 如何自定义类的构造函数? - C++中值初始化默认初始化的区别? - 在Node.js中如何使用C++模块? 回答中引用引用[2][4]。 </think>### C++ 中 `new node()` 括号内内容的解释 在 C++ 中,`new` 操作符用于动态内存分配,它会创建一个对象并调用其构造函数。`new node()` 中的括号用于传递构造函数的参数。括号内的内容取决于 `node` 类的构造函数定义。如果 `node` 是一个自定义类或结构体,括号内需要填写与构造函数参数列表匹配的值。以下是详细说明规则: #### 1. **括号内内容的基本原则** - **无参数构造函数**:如果 `node` 类有一个默认构造函数(即无参数),括号内可以为空:`new node()`。这会调用默认构造函数。 - 例如,引用[4]中的 `BNode * p2 = new BNode();`,`BNode` 结构体可能有一个编译器生成的默认构造函数,因此括号内无需内容。 - **有参数构造函数**:如果 `node` 类定义了参数的构造函数(如 `node(int id)`),括号内必须提供与参数类型匹配的值:`new node(10)`。 - **初始化列表(C++11及以上)**:参考引用[2],C++11 支持大括号初始化(初始化列表),允许在括号内使用 `{}` 语法进行统一初始化。例如:`new node{42}` 或 `new node(42)`。这在数组初始化中更常见,如 `new int[5]{1,2,3}`[^2]。 #### 2. **括号是否可省略?** - 在 C++ 中,`new node` `new node()` 在初始化行为上有细微差别: - `new node`:执行默认初始化。对于内置类型(如 `int`),会初始化值;对于类类型,如果定义了默认构造函数,则调用它。 - `new node()`:执行值初始化。对于内置类型,初始化为 0;对于类类型,调用默认构造函数。这确保对象被正确初始化,避免未定义行为[^4]。 - **建议**:在大多数场景下,推荐使用 `new node()`(括号为空或有参数),以利用值初始化机制防止未初始化错误。 #### 3. **具体示例分析** 假设 `node` 类定义如下: ```cpp class node { public: node(); // 默认构造函数(无参数) node(int id); // 参数构造函数 }; ``` - 使用 `new node()`:括号内为空,调用默认构造函数。 ```cpp node* n1 = new node(); // 括号内无内容 ``` - 使用参数的 `new node()`:括号内填写整数,匹配构造函数参数。 ```cpp node* n2 = new node(42); // 括号内为整数值 ``` 参考引用[4]中的 `BNode` 例子: ```cpp typedef struct BNode { int data; struct BNode* Lson; struct BNode* Rson; } BNode; BNode* p = new BNode; // 默认初始化,data 未初始化 BNode* p2 = new BNode(); // 值初始化,编译器可能将 data 初始化为 0 ``` 这里,`new BNode()` 的括号内为空,因为 `BNode` 是 POD(Plain Old Data)类型,编译器自动生成默认构造函数。 #### 4. **注意事项** - **查看类定义**:括号内内容必须严格匹配类的构造函数签名。如果确定 `node` 的结构,请检查其头文件或源码。 - **C++ 版本影响**:在旧标准(如 C++98)中,`new node()` 可能支持初始化列表;但在 C++11 及以后,允许类似 `new node{arg1, arg2}` 的语法[^2]。 - **内存管理**:使用 `new` 后,记得调用 `delete` 释放内存,避免泄漏。例如:`delete n1;`。 总之,`new node()` 括号内的内容应基于 `node` 类的构造函数要求:如果无参数,则为空;如果有参数,提供相应值。推荐优先使用 `new node()` 形式以确保安全初始化[^4]。 ### 相关问题 1. 在 C++ 中,`new` `new()` 的初始化行为有什么区别? 2. 如何为自定义类设计构造函数以支持 `new` 操作符? 3. C++11 的初始化列表语法如何简化动态内存分配? 4. 在 Node.js 中如何集成 C++ 模块来调用 `new` 创建的动态对象?
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值