我已经使用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.

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


当前回答

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

其他回答

我应该用哪种方法?

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

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

简单的回答是:如果你是c++的初学者,你永远不应该使用new或delete。

相反,你应该使用智能指针,例如std::unique_ptr和std::make_unique(或者很少使用std::shared_ptr和std::make_shared)。这样,您就不必太担心内存泄漏了。即使您更高级,最佳实践通常是将使用new和delete的自定义方式封装到一个专门用于对象生命周期问题的小类(例如自定义智能指针)中。

Of course, behind the scenes, these smart pointers are still performing dynamic allocation and deallocation, so code using them would still have the associated runtime overhead. Other answers here have covered these issues, and how to make design decisions on when to use smart pointers versus just creating objects on the stack or incorporating them as direct members of an object, well enough that I won't repeat them. But my executive summary would be: don't use smart pointers or dynamic allocation until something forces you to.

如果没有new关键字,你就把它存储在调用堆栈上。在堆栈中存储过大的变量将导致堆栈溢出。

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

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

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

方法一(使用new)

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

方法二(不使用new)

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

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

一些简单的例子:

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