我已经使用c++有一段时间了,我一直在想这个新的关键字。简单地说,我是否应该使用它?

使用new关键字…

    MyClass* myClass = new MyClass();
    myClass->MyField = "Hello world!";

没有new关键字…

    MyClass myClass;
    myClass.MyField = "Hello world!";

从实现的角度来看,它们似乎并没有什么不同(但我确信它们确实不同)……然而,我的主要语言是c#,当然第一个方法是我所习惯的。

困难在于方法1很难与std c++类一起使用。

我应该用哪种方法?

更新1:

最近,我为一个超出作用域(即从函数返回)的大数组使用了用于堆内存(或自由存储)的new关键字。在我使用堆栈之前,会导致一半的元素在作用域外损坏,切换到堆使用可以确保元素完好无损。耶!

更新2:

我的一个朋友最近告诉我,使用new关键字有一个简单的规则;每次输入new,都输入delete。

    Foobar *foobar = new Foobar();
    delete foobar; // TODO: Move this to the right place.

这有助于防止内存泄漏,因为您总是必须将删除放在某个地方(即当您剪切并粘贴到析构函数或其他方法时)。


当前回答

我应该用哪种方法?

这几乎从来不是由您的输入首选项决定的,而是由上下文决定的。如果你需要将对象保存在几个堆栈中,或者它对于堆栈来说太重了,你可以将它分配到免费存储中。此外,由于您正在分配一个对象,您还负责释放内存。查找删除操作符。

为了减轻使用免费商店管理的负担,人们发明了像auto_ptr和unique_ptr这样的东西。我强烈建议你看看这些。它们甚至可能对你的打字问题有帮助;-)

其他回答

方法一(使用new)

为自由存储区上的对象分配内存(这通常与堆相同) 要求稍后显式删除对象。(如果你不删除它,你可能会创建一个内存泄漏) 内存一直被分配,直到删除它。(也就是说,你可以返回一个你用new创建的对象) 问题中的例子会泄漏内存,除非删除指针;无论采用哪条控制路径,或者是否抛出异常,都应该始终删除它。

方法二(不使用new)

为堆栈上的对象分配内存(所有局部变量都在堆栈上)。如果分配的对象太多,就有堆栈溢出的风险。 你以后不需要删除它。 当内存超出作用域时,不再分配内存。(也就是说,你不应该返回指向栈上对象的指针)

至于用哪一个;考虑到上述约束条件,您可以选择最适合自己的方法。

一些简单的例子:

如果不想担心调用delete(以及可能导致内存泄漏),就不应该使用new。 如果你想从函数返回指向对象的指针,你必须使用new

简单的答案是肯定的——new()在堆上创建一个对象(不幸的副作用是,您必须管理它的生命周期(通过显式地对它调用delete),而第二种形式在当前作用域的堆栈中创建一个对象,当它超出作用域时,该对象将被销毁。

第二个方法在堆栈上创建实例,以及一些声明为int的东西和传递给函数的参数列表。

第一个方法为堆栈上的指针腾出空间,您已经将其设置为内存中已在堆(或自由存储区)上分配新MyClass的位置。

第一种方法还要求删除用new创建的内容,而在第二种方法中,类在超出作用域(通常是下一个右括号)时自动销毁并释放。

你是将myClass传递给函数,还是期望它存在于函数之外?正如其他人所说,当您不在堆上分配时,这完全是关于范围的问题。当你离开函数时,它(最终)消失了。初学者常犯的一个经典错误是试图在函数中创建某个类的局部对象,并返回它而不将其分配到堆上。我还记得在我早期使用c++时调试这类事情。

c++核心指南R.11:避免显式使用new和delete。

自从这个问题的答案被写出来以来,情况已经发生了显著的变化。具体来说,c++已经发展成为一门语言,标准库现在更加丰富。为什么这很重要?因为两个因素的结合:

使用new和delete有潜在的危险:如果你没有在不再使用时删除所有已分配的内容,那么内存可能会泄漏;永远不要删除当前未分配的资源。 标准库现在提供了封装new和delete调用的智能指针,这样你就不必自己管理免费存储/堆的分配了。标准库和其他地方的其他容器也是如此。

正如链接的文档所示,这已经发展成为c++社区编写更好的c++代码的“核心准则”之一。当然,这条规则也有例外:有人需要编写那些使用new和delete的封装类;但那个人很少是你自己。

补充@DanielSchepler的有效答案: