15

我这样做:

MyClass myObject = *new MyClass();

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

MyClass *myObject = new MyClass();

是否存在性能差异。还是完全使用第二种方法的合乎逻辑的理由?我只是更喜欢使用第一种方法来摆脱指针混淆。

4

3 回答 3

30

两者都不一样!
First 给您一个未定义的行为[Ref 1:]delete或内存泄漏,而 second 如果您稍后调用则不会。

MyClass myObject = *new MyClass();

在 freestore 上分配一个类型的对象,MyClass然后将该对象复制到myObject. 您丢失了指向动态分配对象的指针,因此永远无法释放它。
如果MyClass析构函数有副作用并且您的程序依赖于这些副作用,那么它会给您未定义的行为,如果没有,那么您所拥有的就是一个简单的普通内存泄漏

MyClass *myObject = new MyClass();

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


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

MyClass obj;

好读:

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


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

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

于 2013-06-02T05:14:24.320 回答
24

第一个例子说:在堆栈上为 MyObject 的一个实例分配内存,然后在堆上为另一个实例分配内存,在堆上构造一个,将其内容复制到堆栈上的那个,然后失去对堆的跟踪指针,所以它不能被释放。

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

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

于 2013-06-02T05:19:42.387 回答
5

第一个是废话。

MyClass myObject = *new MyClass();

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

上述陈述与写作相同。

MyClass myObject;

其次是

Leak memory equal to size of MyClass.

首先决定你想要一个对象在栈上还是堆上。

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

MyClass myObject;

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

如果您需要堆上的对象,请执行

MyClass *myObject = new MyClass();

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

  1. 在编译时,您不知道需要创建多少对象。
  2. 多态地使用类。
于 2013-06-02T05:19:37.247 回答