我该如何选择在C ++中存储对象的位置?

时间:2009-09-09 12:56:02

标签: java c++

  

可能重复
  Proper stack and heap usage in C++?

我开始从Java背景学习C ++,一个很大的区别是我不再被迫:

  1. 为对象动态分配内存
  2. 始终使用指针来处理对象
  3. 就像Java中的情况一样。但我很困惑何时应该做什么 - 你能建议吗?

    目前我很想开始做像Java一样的所有事情

    Thing *thing = new Thing();
    thing->whatever();
    // etc etc
    

4 个答案:

答案 0 :(得分:5)

除非你知道为什么需要它们,否则不要使用指针。如果您只需要一段时间的对象,请在堆栈上分配它:

Object object;
object.Method();

如果需要将对象传递给函数,请使用引用:

int doStuff( Object& object )
{
    object.Method();
    return 0;
}

如果需要,只使用指针

  • 类似图形的复杂数据结构或
  • 不同对象类型的数组或
  • 从函数或
  • 返回新创建的对象
  • 在有时需要指定“没有对象”的情况下 - 然后使用空指针。

如果使用指针,则需要在不再需要这些对象时以及在对象的最后一个指针变为不可缓存之前解除分配对象,因为C ++没有内置垃圾回收。为了简化这一点,使用智能指针行std :: auto_ptr或boost :: shared_ptr。

答案 1 :(得分:3)

那很糟糕。你一定会忘记释放它,如果你决定不这样做,你必须处理异常,因为它不会自动释放堆栈。至少使用shared_ptr

shared_ptr<Thing> thing( new Thing() );
thing->whatever();

但它实际上取决于对象的大小和范围。如果你要在一个函数中使用它并且对象没有超大,我建议在堆栈框架中分配它。

Thing thing;
thing.whatever();

但好处是您可以决定何时分配新对象; - )

答案 2 :(得分:1)

使用new运算符,否则可以避免使用new运算符,这种方式会导致内存泄漏和头痛,从而记住对象的生命周期。

C ++的方法是使用基于堆栈的对象,除非你复制它们,否则它们在离开作用域后会自行清理。这种技术(称为RAII)是一个非常强大的技术,每个对象都会照顾自己,有点像GC在Java中为你记忆的方式,但具有清理的巨大优势,因为它以确定的方式进行清理(即你知道什么时候它会被清理干净。)

但是,如果您更喜欢使用对象的方式,请使用share_ptr,它可以为您提供相同的语义。通常,您只能将shared_ptr用于非常昂贵的对象或非常复制的对象。

答案 3 :(得分:1)

您可能需要在堆上分配实例的一种情况是,仅在运行时知道哪个实例将首先创建(与OOP相同):

 Animal* animal = 0;
 if (rand() % 2 == 0)
    animal = new Dog("Lassie");
 else
    animal = new Monkey("Cheetah");

您可能需要的另一种情况是,当您拥有一个不可复制的类时,您必须将其实例存储在标准容器中(这要求其内容可以复制)。一种变体就是你可能希望存储指向复制成本高的对象的指针(不过这个决定不应该在现有的情况下完成)。

在所有情况下,最好使用像shared_ptr和unique_ptr这样的智能指针(将其添加到标准库中),因为它们可以为您管理对象的生命周期。