我有一个应用程序,其中包含大量似乎确实不需要的新对象,实例化的对象在使用后几行后在相同的上下文(函数)中被删除。
假设我可以将它们更改new
为堆栈分配是否安全,或者我必须采取特殊考虑?
这些物体相对较轻,没有大的缓冲区或类似的东西。
编辑 :
我发现的另一点是对象删除顺序更难控制。您必须更加小心事物的创建方式。
除非您根据运行时条件创建不同类型的对象,否则应该没有问题。我的意思是,如果你有类似的东西:
A* pA;
if (condition)
pA = new B();
else
pA = new C();
那么你必须坚持指针; 否则,您将进入对象切片并错过虚拟呼叫。但是,如果您的代码很简单:
A* pA = new A();
// ...
delete pA;
那么你会更好地使用堆栈分配。如果在对象创建和删除之间抛出异常,您将避免问题,这是最明显的优势之一。
[编辑:另一种可能性是覆盖operator new
,正如 Mark B在他的回答中所说。覆盖的主要用途operator new
是优化特定类的内存分配;就您而言,这可能不会影响您。但是,是的,你的类有可能有一个重写operator new
,它会做一些奇怪的事情,在这种情况下,你会改变程序的行为。]
一个好的经验法则是:除非必须,否则不要使用指针。当然,唯一能够决定你是否真的必须这样做的人是你。
我能想到几个考虑因素。
如果指针被多态使用(你的问题暗示不),那么你必须继续使用指针。在这种情况下,将其更改为使用适当的智能指针。
如果您的任何类在operator new
内部覆盖,您可以通过不再调用这些方法来完全改变程序的行为。
否则,由于对象是轻量级的,因此更改为基于堆栈的对象似乎更干净。
这取决于您的特定环境;在没有看到实际代码的情况下,很难给出具体的建议。
但是,您至少可以考虑使用智能指针而不是分配调用的原始new
指针(并因此注意正确调用delete
)。
如果您的对象仅存在于函数范围内,您可能需要考虑boost::scoped_ptr
或 C++11 的std::unique_ptr
.
例如
#include <memory>
void f()
{
std::unique_ptr<SomeClass> p( new SomeClass );
p->DoSomething();
....
// No need to call delete.
// This helps making code exception-safe, and it's useful if you return from the function
// from different points (so you don't have to make different delete calls to properly
// release resources).
}
一般来说,在现代 C++ 代码中,拥有原始指针应该很少在少数地方使用,例如在作为直接资源管理器的类的类边界内(即使在这些情况下,通常也可以使用std::unique_ptr
),或者当你实现你的自己的特殊数据结构等