为什么没有纯虚拟析构函数的隐式默认定义?

Why isn't there an implicit defaulted definition for pure virtual destructor?

我知道如果 class 应该是抽象的,但不包含任何使用定义的方法,有一种技术可以通过使析构函数成为纯虚拟的来实现这一点。

class B{
public:
    virtual ~B() = 0;
}

据我了解,下面示例中的对象应该无法实例化。

#include <iostream>

class A{
public:
    A(){std::cout<<"A::A()"<<std::endl;}
    virtual ~A() = 0;
};


class B : public A{
public:
    B(){std::cout<<"B::B()"<<std::endl;}
};

int main(){
    B b;
}

我知道纯虚函数也可以有定义,在上面的例子中应该为 B 的析构函数定义,但有些东西对我来说是模糊的。是否有任何特殊原因不让纯虚拟析构函数的定义在 C++ 标准中隐式默认,因为对我来说这很有意义。

如果一个函数被声明为纯虚函数,那么这意味着两件事:

  1. 这样声明的class无法实例化

  2. 任何派生的 classes 必须提供方法的定义,否则它们也不能被实例化。

但是,#2 只有在您没有为该纯虚函数声明提供定义时才会发生。如果您确实定义了纯虚函数,那么派生的classes 不需要特别重写那些方法。

因此,如果始终存在纯虚拟析构函数的默认定义,不可能强制用户为派生的 classes 声明析构函数.

在极少数情况下,您有一个 class,您打算将其用作虚拟类型,但没有实际接口(我不明白当您有 没有接口),因此不应该被实例化,但是你也希望用户不必显式定义析构函数,你can do this:

#include <iostream>

class A{
public:
    A(){std::cout<<"A::A()"<<std::endl;}
    virtual ~A() = 0;
};

A::~A() = default; //Yes, this is legal.


class B : public A{
public:
    B(){std::cout<<"B::B()"<<std::endl;}
};

int main(){
    B b;
}

但是,我非常怀疑这种情况在现实中出现的频率是否足以真正重要。在大多数用于虚拟接口的真实类型中,它们具有超出“可以被破坏”的实际虚拟接口。他们需要 virtual 个析构函数,但他们也有其他可以是纯虚函数。因此,它们的析构函数不需要是纯的。