【问题标题】:Should a class with an un-overridden pure virtual destructor be initializable?具有未覆盖的纯虚拟析构函数的类是否可以初始化?
【发布时间】:2014-10-24 21:20:22
【问题描述】:

Common wisdom 是如果你可以通过一个纯虚析构函数来抽象一个类。

引用Herb Sutter

所有基类都应该有一个虚拟析构函数(原因请参阅您最喜欢的 C++ 书籍)。如果该类应该是抽象的(您想阻止实例化它)但它没有任何其他纯虚函数,这是使析构函数纯虚函数的常用技术:

但是,下面的代码使用 GCCVC 为我编译:

#include <iostream>

struct base {
    virtual ~base() = 0;
};

base::~base() { std::cout << "base destructor\n"; }

struct derived : base { };

int main() {
    derived d;
}

C++11 中是否有一些我不知道的变化?

顺便说一句,这个问题的动机是answer I gave five years ago,突然受到commenter的挑战。

【问题讨论】:

  • 为什么不能编译?您正在实例化派生对象,而不是基础对象。而且只有你的基类是抽象的,因为你的派生类有默认的析构函数。
  • by having a pure virtual constructor => by having a pure virtual destructor?
  • @Gluttton 哎呀,谢谢。
  • @Motti:由于 C++98 的析构函数一直被隐式声明为非纯成员(在没有用户声明的情况下)。
  • 纯虚析构函数的目的不是为了让上面的代码不合法​​。就是让这段代码非法:base b;

标签: c++ c++11 abstract-class destructor pure-virtual


【解决方案1】:

derived 类有一个隐式定义(编译器提供)的虚拟析构函数,它不是纯析构函数,它会覆盖基析构函数。因此,derived 不是抽象类。可以实例化。

这与 C++11 无关。从 C++98 开始就是这样。使基类析构函数成为纯虚拟是一种使该类成为抽象类的方法。派生类中编译器提供的析构函数将是非纯虚拟的,这将自动“取消”这些类中的抽象性(假设没有从基类继承其他纯虚拟方法)。

【讨论】:

  • Derived 的析构函数不会覆盖 base 的。想想覆盖意味着什么。
  • @H Walters:呃...是的,派生的析构函数确实会覆盖虚拟基析构函数。这正是覆盖的含义。
  • mea culpa... 我指的是 dtor 的链而不是隐藏的事实,但考虑到将 dtor 描述为压倒一切的标准,它赢了。
  • ...当然必须是这样。链接行为的无关...覆盖是指通过基础调用的行为。这就是我试图过度思考的结果。
猜你喜欢
  • 2016-02-05
  • 2021-03-27
  • 2021-11-01
  • 1970-01-01
  • 2017-04-21
  • 2014-01-09
  • 1970-01-01
  • 1970-01-01
  • 2019-04-20
相关资源
最近更新 更多