3

我知道已经动态分配并使用堆的内存需要使用 delete 手动删除。如果在超出范围的类函数中创建动态对象也是这种情况吗?这是一个片段。

    Fraction* Fraction::add(const Fraction* fr) const{ 
      int gcd;
      Fraction* temp;

      gcd = gcdRecur(num * fr->denom + fr->num * denom, 
                     denom * fr->denom);

      temp = new Fraction((num * fr->denom + fr->num * denom) / gcd, 
                          (denom * fr->denom) / gcd);

      return temp;
   }

在这种情况下, temp 是指向使用“new”的 Fraction 类型的动态对象的指针(对吗?)。如果我将此指针返回到调用类函数“add”的位置,是否需要删除本地指针“temp”?如果是这样,我该如何做到这一点?

编辑:我对在此类成员中使用 new 的(错误)解释是因为 Fraction 对象正在通过指向 Fractions 的指针进行实​​例化(如下所示):

    int main() {
      menu()
      return 0;
    }

    void menu() {
      Fraction* fr1 = 0;
      Fraction* fr2 = 0;
      Fraction* fr3 = 0;
      // ... user chooses to initialize, so fr1, fr2, fr3 no longer null

      // ... user chooses to add. call submenu, pass fr1, fr2, fr3 by POINTERS?
      addMenu(fr1, fr2, &fr3);
    }

看起来很糟糕......这是 addMenu 的标题:

     void addMenu(const FractionTeddyD*, const FractionTeddyD*, FractionTeddyD**);

编辑#2:在不使用“新”的情况下解决。吨

4

5 回答 5

1

您可以使用智能指针,例如std::unique_ptrstd::shared_ptr

 std::unique_ptr<Fraction> Fraction::add(...) const { 

      ...

      std::unique_ptr<Fraction> temp (new Fraction(...));

      return temp;
  }

并且您可以摆脱对删除内存的担忧。

于 2013-11-11T18:25:22.883 回答
1

确实需要删除,否则内存会泄露。你不能在本地删除它,因为调用者需要在函数返回后使用它。一旦不再需要,调用者将不得不将其删除。显然,这很容易出错,这就是为什么您应该始终使用RAII来管理动态资源的原因。

在这种情况下,您应该将返回类型更改为智能指针,例如std::unique_ptr<Fraction>.

另一方面,你为什么要在new这里使用?返回一个值会更简单,而且几乎可以肯定更快。

于 2013-11-11T18:25:24.440 回答
0

c++ 中的指针是按值传递的,这意味着您可以在任何有指针的地方删除对象(只要它尚未被删除)。因为它们本质上只是存储一个地址,这很好,因为当调用 delete 时,它​​知道在哪里以及如何释放内存。

在您的情况下,您将在函数之外删除它,否则返回它是没有意义的。为了避免必须自己管理内存,您实际上应该使用std::unique_ptr

std::unique_ptr<Fraction> Fraction::add(const Fraction* fr) const{ 
  int gcd;

  gcd = gcdRecur(num * fr->denom + fr->num * denom, 
                 denom * fr->denom);

  std::unique_ptr<Fraction> ptr(new Fraction((num * fr->denom + fr->num * denom) / gcd, 
                      (denom * fr->denom) / gcd));

  return ptr;

}

使用这种风格会省去很多麻烦,现在在 c++ 中被认为是惯用的。该参数fr也可以作为 a 传递unique_ptr,要采用这种编码风格,您还需要了解std::shared_ptr哪个代表没有唯一所有权的 ptr(可以存在多个)。

然而真正的问题是当你在堆上创建一个对象而不用对象的地址保存指针时。然后该对象丢失并且无法释放。

于 2013-11-11T18:24:28.937 回答
0

停止使用后,您需要立即删除内存。内存不会为你释放,除非你的编译器有一个内置的内存清除系统,并将它嵌入到你的 *.exe 文件中。

附带说明:您可能不想在add函数中分配新内存。尝试阅读有关重载运算符的信息。当您查找该术语时,您可能会注意到operator +通常返回对类实例的引用。而且我认为这可能是您问题中更好的解决方案。

如果您真的需要指针,并且不想为何时删除它而烦恼,那么有许多存储智能指针的类,例如std::shared_ptr( reference )

于 2013-11-11T18:27:12.483 回答
0

您对可能的小类分数的设计可能不好。

有:

class Fraction {
    public:
    int numerator;
    int denominator;
};

您可以通过引用传递并按值返回:

Fraction Fraction::add(const Fraction& fr) const;
于 2013-11-11T18:35:58.023 回答