C++中的new vs*new

Arc*_*jia 15 c++ stack pointers dynamic

我这样做:

MyClass myObject = *new MyClass();
Run Code Online (Sandbox Code Playgroud)

但是很多人说我应该这样做:

MyClass *myObject = new MyClass();
Run Code Online (Sandbox Code Playgroud)

是否存在性能差异.或者完全使用第二种方法的逻辑原因?我只是喜欢使用第一种方法摆脱指针混淆.

Alo*_*ave 29

两者都不一样!
首先给你一个未定义的行为[参考1:]或内存泄漏,而如果你delete稍后再打电话,则第二个没有.

MyClass myObject = *new MyClass();
Run Code Online (Sandbox Code Playgroud)

MyClass在freestore上分配类型的对象,然后将该对象复制到myObject.你丢失了指向dynanically分配对象的指针,因此永远不能解除分配它.
如果MyClass析构函数有副作用,并且您的程序依赖于那些副作用,那么它会为您提供未定义的行为,如果没有,那么您拥有的是简单的内存泄漏.

MyClass *myObject = new MyClass();
Run Code Online (Sandbox Code Playgroud)

MyClass在freestore上分配类型的对象,并将点myObject分配到放置动态分配的对象的地址.您仍然拥有指向对象的指针,您可以delete稍后通过调用来解除分配.


如果你的问题是,最好的方法是什么,
答案是根本不使用动态分配的对象:

MyClass obj;
Run Code Online (Sandbox Code Playgroud)

好读:

为什么C++程序员应该尽量减少"新"的使用?


[参考1:]
C++ 11标准:3.8.4:

程序可以通过重用对象占用的存储来结束任何对象的生命周期,或者通过使用非平凡的析构函数显式调用类类型的对象的析构函数来结束任何对象的生命周期.对于具有非平凡析构函数的类类型的对象,程序不需要在重用或释放对象占用的存储之前显式调用析构函数; 但是,如果没有显式调用析构函数或者如果没有使用delete-expression(5.3.5)来释放存储,则不应该隐式调用析构函数,并且任何程序都依赖于析构函数产生的副作用有未定义的行为.

  • 为什么在析构函数中放弃具有副作用的堆分配对象会产生未定义的行为? (5认同)
  • @AlexB:因为标准明确地这样说.添加了引用供您参考.此外,它是非常直观的行为,例如,一个关闭文件句柄或析构函数中的描述符永远不会被调用然后UB肯定打开. (2认同)
  • 如果程序_依赖于析构函数的副作用,它只是UB,但这实际上只是一个重言式.仅仅因为析构函数可能会产生副作用,如果它们被忽略,那么泄漏内存只会泄漏内存. (2认同)

Lee*_*ker 23

第一个例子说:在堆栈上为MyObject实例分配内存,然后在堆上为另一个实例分配内存,在堆上构造一个,将其内容复制到堆栈上的内容,然后丢失堆的跟踪指针因此无法释放.

第二个说:在堆栈上分配一个指针,为堆上的MyObject实例分配空间,构造它,并将指针分配给它的地址,以便以后可以释放它.

第二种情况使用更少的内存,更快,并且不会泄漏内存.第一个案例说"我不懂C++".


use*_*353 5

第一个是废话。

MyClass myObject = *new MyClass();
Run Code Online (Sandbox Code Playgroud)

之后的部分=分配内存并创建一个新MyClass对象。第一部分MyClass通过使用 RHSMyClass对象调用复制构造函数来创建一个新对象。然后在 RHS 中分配的内存泄漏,因为您没有保存的指针来删除它。

上述语句与写作相同。

MyClass myObject;
Run Code Online (Sandbox Code Playgroud)

其次是

Leak memory equal to size of MyClass.
Run Code Online (Sandbox Code Playgroud)

首先决定你想要堆栈上还是堆上的对象。

如果你想要堆栈上的一个对象,那么做

MyClass myObject;
Run Code Online (Sandbox Code Playgroud)

这将创建一个 MyClass 对象 - 它适用于大多数目的。

如果你需要堆上的一个对象,那么做

MyClass *myObject = new MyClass();
Run Code Online (Sandbox Code Playgroud)

第一种方式 - 在堆栈上分配更有效。您出于其他原因进行堆分配

  1. 在编译时,您不知道需要创建多少个对象。
  2. 多态地使用类。