【问题标题】:protected constructor versus pure virtual destructor受保护的构造函数与纯虚拟析构函数
【发布时间】:2012-11-23 01:28:07
【问题描述】:

我需要设置一个类继承结构,其中抽象基类只保存成员变量(但没有成员方法)。成员方法将由派生类定义。因此,我需要的是这个帖子:Making a class abstract without any pure virtual methods

从那里的前 2 个答案中,我意识到有两种方法可以实现它:

  • 使析构函数成为纯虚拟的。
  • 使构造函数受到保护。

我很想知道这两种方法之间的区别。是否存在一种应该优先于另一种的情况(或者可能是一些特殊情况,一种可以工作但另一种不行)?我想了想,什么也想不出来。

我在这里(Is there a use for making a protected destructor virtual?、C++: Protected Class Constructor、Should an abstract class' destructor be pure virtual?)搜索了一些帖子的答案,试图将一些东西放在一起,但我无法得出结论。

【问题讨论】:

    标签: c++ inheritance


    【解决方案1】:

    主要区别在于

    Base * ptr = new Derived;
    delete ptr;
    

    使用虚拟析构函数是合法的,没有它就会有 UB。另外dynamic_cast 至少需要一个虚函数。
    因此,如果您想要多态行为,请使用(纯)虚拟析构函数。如果您不想要它,请使用受保护的构造函数并且不要为多态性(vtables)支付开销。但随后声明析构函数也受保护,以防止通过基指针删除。

    【讨论】:

    • 这并没有真正回答 OP 的问题。非纯虚拟析构函数可以与受保护的构造函数一起使用,并且您的示例代码将表现出定义的行为。您正在谈论一个相关但正交的问题。
    【解决方案2】:

    这两种方式都通过使用完全不同的机制来达到预期的效果。在我看来,protected constructor 更具表现力,因为它完全符合您的问题描述。 Pure virtual destructor 不是一个自然的解决方案,可能需要额外的文档来解释其目的。即使可以跳过它,它也会强制子类实现析构函数。

    【讨论】:

    • 我读到,如果您没有在派生类中显式实现析构函数,那么为它们自动生成的析构函数就足够了。所以纯虚析构函数并不强制子类实现它们的析构函数。
    • @Wutz,那有什么目的呢?
    • @Michael Krelin - 黑客:在没有纯虚方法的情况下使基类抽象。它对于允许基类为其虚拟方法定义默认实现并仍然防止它被直接实例化很有用。
    猜你喜欢
    • 2016-01-22
    • 2020-03-06
    • 2023-03-23
    • 2013-11-03
    • 2012-11-06
    • 2012-01-28
    • 2012-04-13
    • 2018-06-15
    • 2014-07-25
    相关资源
    最近更新 更多