什么时候在C++中使用new?

Sum*_*din 8 c++ oop

什么是什么时候使用"新"来创建一个类的实例的好政策?我已经习惯了一段时间编程C++,但我仍然不确定何时才是这样做的最佳时机:

MyClass thing(param1, param2);
Run Code Online (Sandbox Code Playgroud)

对此:

MyClass* thing;
thing = new MyClass(param1, param2);
Run Code Online (Sandbox Code Playgroud)

有什么建议?

GMa*_*ckG 22

在设计方面,尽可能使用自动(堆栈)分配.每当您需要将对象的生命周期延长到某个范围之外时,就会动态分配它.

即便如此,也绝不动态分配原始内容.始终将它们包装到某种包装器中,该包装器实现了Scope-Bound Resource Management(SBRM,首先以哑/尴尬的名称资源获取初始化或RAII而闻名).也就是说,动态分配应该保存在将要清理的自动对象中自动起来!

一个很好的例子是std::vector:你不能泄漏内部的内存vector,因为它的析构函数是在内存应该被释放的每个场景中运行的,它会为你释放它.auto_ptr是标准库中第一个也是唯一一个可用的智能指针,但它非常糟糕.更好的是使用shared_ptrBoost和/或TR1和/或C++ 0x中可用的许多其他流行的智能指针.

性能方面,堆栈上分配的对象可以非常快速地完成(堆栈大小增加了每个函数调用,所以所有需要的内存都是通过简单的指针移动预先分配的.)相反,动态分配通常需要更多时间.使用自定义分配方案可以获得快速的动态分配,但即使是最好的也会比堆栈分配慢.

有时,您可能会发现花费太多时间复制周围的物体.在这种情况下,动态分配它并仅仅移动指针可能是值得的.但是,请注意我说"找到".通过剖析和测量,从不猜测,您可以找到这种变化.

所以:尽可能自动分配,需要时动态分配.

  • +1特别是对于RAII来说,这是一个愚蠢和尴尬的名字. (2认同)

Car*_*icz 5

第一种方法是在堆栈上创建一个本地实例,当调用函数退出时,该实例就会消失.第二个创建一个保留在堆上的实例,直到(以及如果)再次显式释放它.选择取决于您对对象的控制和生命周期.


Pra*_*rav 0

 MyClass thing(param1, param2); //memory for thing is allocated on the process stack(static allocation)

 MyClass* thing;
 thing = new MyClass(param1, param2); //memory is allocated dynamically on the heap(free store) for thing
Run Code Online (Sandbox Code Playgroud)

区别就在这里:

 int main()
 { 
   {
    MyClass thing(param1, param2); //thing is local to the scope
   } //destructor called for thing
   //cannot access thing (thing doesn't exist)
 } 

 int main()
 {
   {
     MyClass* thing;
     thing = new MyClass(param1, param2);
   }
  //the object pointed to by thing still exists
   //Memory leak
 }  
Run Code Online (Sandbox Code Playgroud)

对于大对象,您必须动态分配内存(使用 new),因为进程堆栈的大小有限。

  • 不是很有帮助。它给人的印象是您应该明确使用“new”。始终将其隐藏在 RAII 包装器后面,以便当包装器超出范围时它会被删除。 (2认同)