几个小时前,我摆弄了记忆泄漏问题,事实证明,我确实有一些关于虚拟灾害器的基本内容!让我说解释一下我的课程设计。

class Base
{
  virtual push_elements()
  {}
};

class Derived:public Base
{
vector<int> x;
public:
   void push_elements(){ 
      for(int i=0;i <5;i++)
         x.push_back(i); 
   }
};

void main()
{
    Base* b = new Derived();
    b->push_elements();
    delete b;
}

边界检查器工具报告了派生类向量的内存泄漏。而且我发现驱动器不是虚拟的,并且未调用派生的类驱动器。当我制作灾难虚拟的时,它令人惊讶地解决了。即使未调用派生的类破坏者,矢量也不会自动划分?这是界限工具中的怪癖,还是我对虚拟破坏者的理解是错误的?

有帮助吗?

解决方案

当基类没有虚拟驱动器导致不确定的行为时,通过基类指针删除派生的类对象。

您观察到的(对象的派生级部分永远不会被破坏,因此其成员永远不会被划定)可能是许多可能的行为中最常见的,也是一个很好的例子,说明为什么确保您的灾难是重要的例子实际使用多态性时虚拟。

其他提示

如果基类没有虚拟破坏者,则代码的结果是未定义的行为,不一定是被调用的错误驱动器。这大概是Boundschecker诊断的。

尽管这在技术上是未定义的,但您仍然需要了解最常见的失败方法才能诊断它。这种常见的失败方法是调用错误的破坏者。我不知道有任何其他方式将失败的实现,尽管我只使用两个实现。

发生这种情况的原因是当您尝试覆盖非虚拟成员函数并通过基本指针调用“错误”函数的原因相同。

如果攻击函数不是虚拟的,则将调用基本驱动器。基本击振子清理基本对象并完成。基本对象驱动器无法了解派生对象,它必须是派生的驱动器,而与任何函数一样,做到这一点的方法就是使destructor virtual virtual。

从C ++常见问题解答lite:“我的破坏者什么时候应该虚拟?”阅读 这里. 。 (顺便说一下,C ++常见问题解答是您与C ++有关的所有问题的绝佳来源)。

在C ++中 微不足道的破坏者 是一个递归定义的概念 - 当班级(和每个基类)都有一个微不足道的破坏者时,编译器为您编写的攻击函数。 (有一个类似的概念称为琐碎的构造函数。)

当对象中包括具有非平凡破坏者的对象时(例如 vector 在您的示例中),然后是外部物体的击振(就像您的 Derived)不再是微不足道的。即使您没有编写Destructor,C ++编译器也会自动编写攻击函数,该驱动器称为任何具有破坏者的成员的破坏者。

因此,即使您没有写任何东西,也仍然适用编写非虚拟驱动器的警告。

如果您来自C#,那么您就想知道为什么向量不会自动退出。但是在C ++中,除非您使用Microsoft管理的扩展名(C ++/CLI),否则自动内存管理无法使用。

由于基类中没有破坏者,因此派生的类对象将永远不会被释放,因此您可以泄漏为派生类的向量数据成员分配的内存。

Destructor是类的成员函数,其名称是类名称的同一名称,并在tilde符号(〜)之前。当对象脱离范围时,驱动器用于摧毁类的对象,或者您可以说所有清理班级破坏都应在灾难中进行。当对象脱离范围时,在集体中对象的构造过程中分配了所有内存(或内存释放)。

在示例上找到更多详细信息 边界检查

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top