繁体   English   中英

删除C++中继承的类指针数组

[英]Delete Inherited class Pointer Array in C++

我有一个 A 类,例如:

class A
{
   int a;
}

而且,我还有 B 类继承了 A 类:

class B : public A
{
   int b;

public:
   static A** ReturnAPtrArray(int size);
}

然后,我使 Array 在 B 类中具有 A 类指针。

A** B::ReturnAPtrArray(int size)
{
   A** array = new A*[size];
   for(int i = 0; i< size; i++)
   {
      array[i] = new A();
   }

   return array;
}

在主函数中,我调用了 B 类的 ReturnAPtrArray() 函数。

void main(void)
{
   int size = 100;
   A** aptrArray = B::ReturnAPtrArray(size);

   --------Do Something

   delete[] aptrArray;
}

这个主函数会导致内存泄漏。 所以我删除了这样的每个指针:

void main(void)
{
    int size = 100;

    A** aptrArray = B::ReturnAPtrArray(size);

    --------Do Something

    for(int i = 0; i< size; i++)
    {
       delete aptrArray[i];
    }

    delete[] aptrArray;
}

修改main func后,内存泄漏消失。

如果我想释放内存,我应该删除指针数组中的所有指针吗?

还有其他选择吗?

如果我想释放内存,我应该删除指针数组中的所有指针吗?

是的你应该

delete[]只删除它自己的数组。 由于您有一个指针数组,您必须单独删除每个指针元素。

至于其他选项,您可以使用智能指针。

例子:

#include <memory>
#include <vector>

int main()
{
    std::vector<std::shared_ptr<A>> array;
    for(int i = 0; i < 100; i++)
    {
        array.push_back(std::make_shared<B>());
    }
}

当数组超出范围时,它会自行删除

区分多态所有权和多态使用很重要。 多态所有权是指您想要拥有未知类型的事物(或许多事物)。 多态使用是当你不知道它是什么时想要操纵它。 你的例子并没有真正说明你为什么使用继承,所以我会解释两者。

如果您只创建 B,只需将它们声明为 B。 如果您想将一组 B 传递给一个不知道它们是 B 的函数,只需创建一个 B 向量并将它们作为指向 A 的指针传递。
像这样 ...

std::vector<B> myBs(5);   // create 5 default B's
for (const auto& thisB: myBs) Fn(&thisB); // cast a ptr-to-B to a ptr-to-A

像这样保持简单会让你的生活更简单,因为这段代码是类型安全的。

另一方面,如果您想拥有一个可能是 B 或可能不是,但绝对继承自 A 的事物列表。使用类似这样的东西。

std::vector<std::unique_ptr<A>> my_maybe_bs_might_not;

这种模式可能表面上看起来更简单,但它有很多问题。 例如,您必须使用必须使用虚拟析构函数。 这反过来又调用了 3/5规则 简单地说,如果编译器不知道一个东西是什么,你必须告诉它如何移动/复制它。 如果不这样做,编译器可能会做错事。

一个更简单的(假设你有 C++17)多态所有权的方案是使用一个变体 当你使用一个变体时,你必须列出它可能是的所有东西,这可以包括智能指针。

using MaybeB = std::variant<std::unique_ptr<B>, std::unique_ptr<C>>;
std::vector<MaybeB> my_maybe_bs_might_not;

这种模式允许编译器为您生成所有正确的代码,同时使添加新类变得简单。 唯一的缺点是因为你必须列出你可能想要拥有的所有东西。 这对于库级系统来说是一个糟糕的选择,库的用户可能想要编写他们自己的类(从 A 派生)并将其添加到您的列表中。

一般建议是尽可能选择最简单的方案,这通常意味着避免多态所有权,除非确实需要。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM