简体   繁体   English

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

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

I have a class A like:我有一个 A 类,例如:

class A
{
   int a;
}

And, Also I have class B that inherited class A:而且,我还有 B 类继承了 A 类:

class B : public A
{
   int b;

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

Then, I make Array having A class Pointer in class B.然后,我使 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;
}

In main func, I Called class B's ReturnAPtrArray() func.在主函数中,我调用了 B 类的 ReturnAPtrArray() 函数。

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

   --------Do Something

   delete[] aptrArray;
}

This main func makes memory leak.这个主函数会导致内存泄漏。 So I deleted every pointers like this:所以我删除了这样的每个指针:

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;
}

After modified main func, memory leaks were disappeared.修改main func后,内存泄漏消失。

If I want to free memory, should I delete all pointers in Pointer Array?如果我想释放内存,我应该删除指针数组中的所有指针吗?

Is there any other options?还有其他选择吗?

If I want to free memory, should I delete all pointers in Pointer Array?如果我想释放内存,我应该删除指针数组中的所有指针吗?

Yes you should是的你应该

delete[] deletes only the array it self. delete[]只删除它自己的数组。 Since you have a array of pointers you must delete every pointer element individually.由于您有一个指针数组,您必须单独删除每个指针元素。

As for other options you can use smart pointers.至于其他选项,您可以使用智能指针。

Example:例子:

#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>());
    }
}

when the array goes out of scope it deletes it self当数组超出范围时,它会自行删除

It is important to distinguish between polymorphic-ownership and polymorphic use.区分多态所有权和多态使用很重要。 Polymorphic ownership is when you want to own a thing (or many things) that are are of an unknown type.多态所有权是指您想要拥有未知类型的事物(或许多事物)。 Polymorphic use is when you want to manipulate a thing when you don't know what it is.多态使用是当你不知道它是什么时想要操纵它。 Your example doesn't really make clear why you use inheritance at all, so I will explain both.你的例子并没有真正说明你为什么使用继承,所以我会解释两者。

If you only create B's just declare them as B's.如果您只创建 B,只需将它们声明为 B。 If you want to pass a set of B's to a function that doesn't know they are B's, the simply create a vector of B's and pass them as pointer-to-A.如果您想将一组 B 传递给一个不知道它们是 B 的函数,只需创建一个 B 向量并将它们作为指向 A 的指针传递。
Like this ...像这样 ...

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

Keeping it simple like this will make your life a lot simpler, as this code is type-safe.像这样保持简单会让你的生活更简单,因为这段代码是类型安全的。

If on the other hand you want to own a list of things that might be a B, or might not, but definitely inherits from A. Use something like this.另一方面,如果您想拥有一个可能是 B 或可能不是,但绝对继承自 A 的事物列表。使用类似这样的东西。

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

This pattern might seem superficially simpler, but it comes with a lot of gotcha's.这种模式可能表面上看起来更简单,但它有很多问题。 For example, you must use must use a virtual destuctor.例如,您必须使用必须使用虚拟析构函数。 This in turn invokes the rule-of-3/5 .这反过来又调用了 3/5规则 Simply put, if the compiler doesn't know a thing is, you have to tell it how it can be moved/copied.简单地说,如果编译器不知道一个东西是什么,你必须告诉它如何移动/复制它。 If you don't, the compiler will probably do the wrong thing.如果不这样做,编译器可能会做错事。

A simpler (assuming you have C++17) scheme for polymorphic-ownership is using a variant .一个更简单的(假设你有 C++17)多态所有权的方案是使用一个变体 When you use a variant, you must list all things it might be, this can include smart pointers.当你使用一个变体时,你必须列出它可能是的所有东西,这可以包括智能指针。

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

This pattern allows the compiler to generate all the right code for you, while making it simple to add new classes.这种模式允许编译器为您生成所有正确的代码,同时使添加新类变得简单。 The only downside is that because you must list all the things you might want to own.唯一的缺点是因为你必须列出你可能想要拥有的所有东西。 This makes it a bad choice for a library-level system, where the user of the library might want to write their own class (derived from A) and add it to your list.这对于库级系统来说是一个糟糕的选择,库的用户可能想要编写他们自己的类(从 A 派生)并将其添加到您的列表中。

The general advice is to pick the simplest scheme possible, which in general means avoiding polymorphic ownership unless that is really required.一般建议是尽可能选择最简单的方案,这通常意味着避免多态所有权,除非确实需要。

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

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