为什么定义纯虚函数有意义?

2022-01-24 00:00:00 class polymorphism c++ virtual-functions

Scott 在《Effective C++, 3rd Edition, pg.》上说.43 要创建一个抽象类,我们只需要给它一个纯虚析构函数:

Scott said on Effective C++, 3rd Edition, pg. 43 that to make an abstract class, we just need to give it a pure virtual destructor:

class AWOV {                  // AWOV = "Abstract w/o Virtuals"
public:
  virtual ~AWOV() = 0;        // declare pure virtual destructor
};

然后,他继续说有一个转折:我们必须为纯虚析构函数提供一个定义:

Then, he went on said that there is one twist: we must provide a definition for the pure virtual destructor:

AWOV::~AWOW() {}              // definition of pure virtual dtor

我的问题是,通过指定 = 0,对于纯虚函数,我们是说该函数不能对声明此纯虚函数的类有任何定义.

My question is, by specifiying = 0, for pure virtual functions, we are saying that the function cannot have any definition for the class where this pure virtual function is declared.

为什么在这里为纯虚析构函数提供定义(即使是空的)也可以?

Why is it OK to provide a definition (even it is empty) for the pure virtual destructor here?

推荐答案

我们是说函数不能对声明这个纯虚函数的类有任何定义."

"we are saying that the function cannot have any definition for the class where this pure virtual function is declared."

这不是纯虚拟的意思.纯虚拟只意味着包含的类不能被实例化(是抽象的),所以它必须被子类化,并且子类必须覆盖该方法.例如,

That's not what pure virtual means. Pure virtual only means that the containing class cannot be instantiated (is abstract), so it has to be subclassed, and subclasses must override the method. E.g.,

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

A::~A() {}

struct B : A {};

int main()
{
    A a;  // error
    B b;  // ok
}

这里,B 析构函数是隐式定义的.如果它是另一种纯虚拟方法,则必须显式覆盖它:

Here, the B destructor is implicitly defined. If it was another method that is pure virtual, you'd have to explicitly override it:

struct A {
    virtual void foo() = 0;
};

void A::foo() {}

struct B : A {};

int main()
{
    B b;  // error
}

当基类必须是抽象的但仍提供一些默认行为时,需要为纯虚方法提供定义.

Providing a definition for a pure virtual method is desirable when the base class must be abstract but still provide some default behavior.

在析构函数的特定情况下,它必须提供,因为它会被自动调用 当子类实例被销毁时.尝试使用没有定义的纯虚析构函数实例化类的子类的程序将不会通过链接器.

In the specific case of a destructor, it has to be provided because it will be called automatically when subclass instances are destroyed. A program that tries to instantiate a subclass of a class with a pure virtual destructor without a definition will not pass the linker.

相关文章