C++ 向量中的内存管理<;T>;在c++;

C++ 向量中的内存管理<;T>;在c++;,c++,memory-management,memory-leaks,C++,Memory Management,Memory Leaks,我有一个名为Animal的类,它有一个虚拟的方法,因此该类成为虚拟类 class Animal { virtual double eat() = 0; }; 我还有两个类,它们是猫和狗,这些类继承自动物 还有四等舱——动物园——还有一块地 vector<Animal *> animals; 媒介动物; 我正在将猫和狗实例推送到动物园对象的动物向量 在任何时候,我想清除动物园实例,我也希望这个对象的向量被删除。我还想把这个物体的向量的物体删除 我到底该怎么办。 除zo

我有一个名为Animal的类,它有一个虚拟的方法,因此该类成为虚拟类

class Animal
{ 
   virtual double eat() = 0;
};
我还有两个类,它们是猫和狗,这些类继承自动物

还有四等舱——动物园——还有一块地

  vector<Animal *> animals;
媒介动物;
我正在将猫和狗实例推送到动物园对象的动物向量

在任何时候,我想清除动物园实例,我也希望这个对象的向量被删除。我还想把这个物体的向量的物体删除

我到底该怎么办。 除zoo之外的所有类都只有浮点字段(没有指针)。(浮动a、b等) 所以我们可以说,没有必要处理动物物体,因为它们没有任何指针

我应该在哪里写析构函数。在一个基类(动物)或一个子类(猫-狗)中,或者不在任何地方
或者我应该如何编写这些析构函数

首先,您需要声明一个give
动物
虚拟析构函数:

class Animal
{ 
   virtual double eat() = 0;
 public:
   virtual ~Animal() {}
};
这是必需的,这样在
动物
指针上调用
删除
将调用指针指向的对象类型的析构函数。在没有虚拟析构函数的情况下执行此操作会导致未定义的行为

接下来,您需要对所有动态分配的
动物调用
delete

for (auto a : animals)
  delete a;
然后,可以清除向量:

animals.clear();
如果您需要将
动物
用于其他用途,则需要此选项。您不需要在
zoo
析构函数中执行此操作


或者,您可以使用
std::vector
忘记手动内存管理。

首先,您需要声明一个give
Animal
虚拟析构函数:

class Animal
{ 
   virtual double eat() = 0;
 public:
   virtual ~Animal() {}
};
这是必需的,这样在
动物
指针上调用
删除
将调用指针指向的对象类型的析构函数。在没有虚拟析构函数的情况下执行此操作会导致未定义的行为

接下来,您需要对所有动态分配的
动物调用
delete

for (auto a : animals)
  delete a;
然后,可以清除向量:

animals.clear();
如果您需要将
动物
用于其他用途,则需要此选项。您不需要在
zoo
析构函数中执行此操作


或者,您可以使用
std::vector
而不必考虑手动内存管理。

让我补充一点,
std::shared\u ptr
可能是更好的选择。然而,
unique\u ptr
shared\u ptr
都不是完美的。@cmaster我希望动物园拥有它的动物,所以
shared\u ptr
不是最好的选择。但我认为这两种方式都没有足够的信息。我不想以任何方式批评你,我只是想补充你的答案,可能有更好的选择。在类似的情况下,有大量的用例需要
共享\u ptr
。@cmaster不用担心,我并没有把它当作批评:-)@bttb据我所知,你只需要循环
动物
删除
动物园
析构函数中的元素。对于其他类,它听起来像是默认的,编译器生成的析构函数就足够了。然而,
unique\u ptr
shared\u ptr
都不是完美的。@cmaster我希望动物园拥有它的动物,所以
shared\u ptr
不是最好的选择。但我认为这两种方式都没有足够的信息。我不想以任何方式批评你,我只是想补充你的答案,可能有更好的选择。在类似的情况下,有大量的用例需要
共享\u ptr
。@cmaster不用担心,我并没有把它当作批评:-)@bttb据我所知,你只需要循环
动物
删除
动物园
析构函数中的元素。对于其他类,它听起来像是默认的,编译器生成的析构函数就足够了。