重构为RAII时可以遇到问题吗?

时间:2013-01-29 17:00:15

标签: c++ raii

我有一个很多新的应用程序似乎不需要,实例化的对象在使用后会在相同的上下文(函数)中删除几行。

可以安全地假设我可以将那些new更改为堆栈分配,还是我需要特别考虑?

这些物体相对较轻,没有大缓冲物或任何其他物体。

编辑:

我发现的另一点是对象删除顺序更难控制。你必须更加小心如何创造事物。

3 个答案:

答案 0 :(得分:3)

除非您根据运行时条件创建不同类型的对象,否则您应该没有问题。我的意思是,如果你有类似的东西:

A* pA;
if (condition)
  pA = new B();
else
  pA = new C();

然后你必须坚持指针;否则,你会进入对象切片和错过虚拟呼叫。但如果你的代码很简单:

A* pA = new A();
// ...
delete pA;

然后你会更好地使用堆栈分配。如果在对象创建和删除之间抛出异常,您将避免出现问题,以确定最明显的优势之一。

[编辑:另一种可能性是覆盖operator new,正如Mark B所说in his answer。覆盖operator new的主要用途是优化特定类的内存分配;在你的情况下,这可能不会影响你。但是,是的,您的类有可能覆盖operator new,这会产生奇怪的事情,在这种情况下,您将改变程序行为。]

一个好的经验法则是:除非必须,否则不要使用指针。当然,唯一有能力决定你是否真的必须的人就是你。

答案 1 :(得分:2)

我可以想到几个考虑因素。

如果多态地使用指针(你的问题暗示没有)那么你必须继续使用指针。在这种情况下,将其更改为使用适当的智能指针。

如果您的任何类在内部覆盖operator new,则可以通过不再调用这些方法来完全改变程序的行为。

否则,因为对象是轻量级的,所以更改为基于堆栈的对象似乎更清晰。

答案 2 :(得分:1)

这取决于你的具体情况;没有看到实际的代码,很难给出具体的建议。

但是,您至少可以考虑使用智能指针而不是分配调用new原始指针(并因此注意正确调用delete })。

如果您的对象仅存在于函数范围内,您可能需要考虑boost::scoped_ptr或C ++ 11的std::unique_ptr

e.g。

#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),或者当您实现自己的特殊数据结构时等。