当前位置: 首页 > 知识库问答 >
问题:

虚拟析构函数用例

阳长恨
2023-03-14

我读过一些文章,正如他们所说,主要的虚拟析构函数用例是:

>

  • 派生类可能具有来自堆的动态数据分配,即“拥有”该数据对象。所以,他们需要在析构函数中使用一些删除例程。通过基类指针删除需要在所有派生类中声明虚拟析构函数,直到那些具有动态数据分配的析构函数(基类也需要它)

    此类具有< code >虚拟方法。但这对我来说不清楚。仅仅通过基类指针调用< code >虚拟方法总是会导致派生实现最多的调用。他们唯一的例外是建造阶段。字面上,在它< code>this对象还不是派生类型,即使以后会是。好吧,那毁灭阶段呢?据我所知,这条规则是倒序的。不管层次结构中的某个类的析构函数是否被声明为< code>virtual,在每个析构函数中< code>this指针都被当作这个类类型使用,任何派生的类都已经由于< code>virtual d-r而被销毁,或者没有被销毁(假设在某些设计中这是可以的)。也许是这样,为什么d-r一定是虚的?Vtable会有派生类的条目,从d-r调用某个基类中的< code>virtual方法会导致UB?好的,但是这条规则只适用于当这个类在d-r中调用一些< code >虚拟方法,并且它们在派生类中有实现的情况。

    我的观点是,也有可能没有动态数据分配,在所有的层次结构中没有虚方法,但是派生的析构函数仍然可以在删除时完成一些关键的任务(同步、解锁等等)。而且我们需要基类的虚拟d-r。这种情况可能是不良设计的结果。

    但无论如何,某些公共类的开发人员不能100%知道派生类是否会使用d-r中的某些虚拟方法,或分配动态数据。所以,我是否正确地说,任何公共类(未声明为final)都必须将d-r声明为virtual?只有<code>final</code>关键字保证指向该类的任何指针始终是这种类型,因此可以安全地非虚拟删除。

  • 共有1个答案

    广晔
    2023-03-14

    如果通过指向基类的指针删除了一个派生对象,那么(也只有那时)基类析构函数必须是虚的。否则就是未定义的行为。没有其他相关规定。

    如果这个类有一个虚函数,那么就不会引入开销。如果该类没有任何其他虚函数,那么基类设计者必须考虑增加虚析构函数的运行时损失与该类的用户试图通过基类指针删除派生对象的风险之间的权衡。

    这里有一个类似讨论的链接,带有标准引用

     类似资料:
    • 在C 11中,我们能够声明一个析构函数是自动生成的: 此外,我们可以将析构函数声明为纯虚: 我的问题是:如何将析构函数声明为自动生成和纯虚拟?看起来以下语法不正确: 这一个也不是: 也不是这个: 编辑:关于问题目的的一些澄清。基本上,我希望一个空类是不可实例化的基类,但派生类是可实例化的,那么该类必须有一个纯虚拟析构函数。但另一方面,我不想在.cpp文件中提供定义。因此,我需要某种与等效的机制。我

    • 在这些关于C 11/14标准的幻灯片中,在幻灯片15中,作者写道,“许多经典的编码规则不再适用于C 11中”。他提出了三个示例的列表,我同意三法则和内存管理。 然而,他的第二个例子是“具有虚拟成员的虚拟析构函数”(仅此而已)。这是什么意思?我知道必须将基类析构函数声明为虚拟,以便调用正确的析构函数,如果我们有类似的东西 这里很好地解释了:什么时候使用虚拟析构函数? 但是,如果您有虚拟成员,现在在C

    • 每个人都知道基类的分解器通常必须是虚拟的。但是派生类的析构函数是什么?在 C 11 中,我们有关键字“override”,并且能够显式使用默认析构函数。 在子类的析构函数中同时使用关键字“覆盖”和“=默认”是否正确?在这种情况下,编译器会生成正确的虚拟析构函数吗? 如果是,那么我们是否可以认为这是好的编码风格,我们应该总是这样声明派生类的析构函数,以确保基类析构函数是虚的?

    • 我一直在使用越来越多的C11,我遇到了一些我在任何地方都找不到的东西。当我们从基指针中删除派生类时,我们需要有虚拟析构函数;但有时父析构函数需要“纯”,这在C中是不可能的。所以,我的问题是,默认值是否可以用于虚拟析构函数?我已经试过了,而且效果不错,但我不知道它是否安全,因为互联网上没有任何关于它的信息。 编辑:为了澄清这个问题,我说的是使用

    • 我理解,只要你有一个多态基类,基类就应该定义一个虚拟析构函数。因此,当删除指向派生类对象的基类指针时,它将首先调用派生类的析构函数。如果我错了,请纠正我。 此外,如果基类析构函数是非虚拟的,那么删除指向派生对象的基类指针将是未定义的行为。如果我错了也纠正我。 所以我的问题是:为什么当基类析构函数非虚拟时,对象不会被正确销毁? 我假设这是因为虚拟函数具有某种表,每当调用虚拟函数时都会记住和查阅该表。

    • 用多态性处理动态分配的类层次结构中的对象时存在一个问题。如果delete运算符用于指向派生类对象的基类指针,而程序中又显式地用该运算符删除每一个对象,那么,不管基类指针所指向的对象是何种类型,也不管每个类的析构函数名是不相同的这样一种情况,系统都会为这些对象调用基类的析构函数。 这种问题有一种简单的解决办法,即将基类析构函数声明为虚析构函数。这样就会使所有派生类的析构函数自动成为虚析构函数(即使它