受保护的构造函数与纯虚析构函数

6
我需要设置一个类继承结构,其中抽象基类仅包含成员变量(但没有成员方法)。成员方法将由派生类定义。因此,我需要这篇文章:Making a class abstract without any pure virtual methods 从那里的前两个答案中,我意识到有两种实现方式:
  • 使析构函数为纯虚函数。
  • 将构造函数设为受保护状态。
我很好奇这两种方法之间的区别。是否有一些场景应该优先考虑其中一种(或者在某些特殊情况下,其中一种会起作用而另一种不会)?我思考了一下,但是想不出任何结果。
我查阅了一些帖子的答案(Is there a use for making a protected destructor virtual?, C++: Protected Class Constructor, Should an abstract class' destructor be pure virtual?),试图整理一些信息,但我无法得出结论。
2个回答

3

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


我读到过,如果您在派生类中没有显式实现析构函数,则为它们自动生成的析构函数已足够。因此,纯虚析构函数不会强制子类实现其析构函数。 - Wutz
@Wutz,那么目的是什么呢? - Michael Krelin - hacker
@Michael Krelin - 黑客:将基类定义为抽象类但不包含纯虚函数。这对于允许基类为其虚函数定义默认实现,同时防止直接实例化它非常有用。 - Wutz

3
主要区别在于
Base * ptr = new Derived;
delete ptr;

如果使用虚析构函数,则是合法的,否则会产生未定义行为。此外,dynamic_cast需要至少一个虚函数。
因此,如果您想要多态行为,请使用(纯)虚拟析构函数。如果不需要它,请使用受保护的构造函数,并避免为多态性(vtable)支付额外开销。但是请将析构函数声明为受保护的,以防止通过基类指针删除对象。


1
这并没有真正回答OP的问题。非纯虚析构函数可以与受保护的构造函数一起使用,您的示例代码将表现出定义良好的行为。您正在谈论一个相关但正交的问题。 - Thomas Eding

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接