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

Qia*_* Xu 20 c++ polymorphism virtual-functions class

斯科特在Effective C++上说,第3版,pg.43要创建一个抽象类,我们只需要给它一个纯虚拟析构函数:

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

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

AWOV::~AWOW() {}              // definition of pure virtual dtor
Run Code Online (Sandbox Code Playgroud)

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

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

Fre*_*Foo 11

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

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

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

A::~A() {}

struct B : A {};

int main()
{
    A a;  // error
    B b;  // ok
}
Run Code Online (Sandbox Code Playgroud)

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

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

void A::foo() {}

struct B : A {};

int main()
{
    B b;  // error
}
Run Code Online (Sandbox Code Playgroud)

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

在析构函数的具体情况下,被提供,因为它会自动被调用时,子类的实例被破坏.尝试使用没有定义的纯虚拟析构函数实例化类的子类的程序将不会传递链接器.


BCS*_*BCS 6

使它成为纯粹的力派生(非抽象)类来实现自己的.

提供实现允许派生类调用基类行为(默认情况下析构函数会执行).

  • @LuchianGrigore如果想要实例化,它会使派生类在继承行的某个地方实现它们,不是吗? (5认同)
  • "使它成为纯粹的力量派生类来实现自己的." 并不是的. (3认同)
  • @MooingDuck在你的代码中,派生类确实实现了自己的析构函数(自动). (3认同)

Luc*_*ore 5

有2例.

纯虚拟析构函数

该案例由标准专门处理.

12.4析构函数[class.dtor]

9)析构函数可以声明virtual(10.3)或纯粹virtual(10.4); 如果在程序中创建了该类或任何派生类的任何对象,则应定义析构函数.如果类具有带虚拟析构函数的基类,则其析构函数(无论是用户还是隐式声明)都是虚拟的.

析构函数的情况是不同的,因为所有析构函数都以构造的相反顺序在继承hierearchy中调用(假设正确删除),即使没有明确说明.因此,当对象被删除时,将调用基类析构函数 - 这就是它需要实现的原因.

纯虚方法

这些与析构函数的不同之处在于它们不需要实现,也不需要实现.缺少需求的区别在于,当一个Derived::foo()被调用时,它不会自动调用Base::foo()(不是它可以,因为它可以或不可以实现).

为什么要实现纯virtual方法取决于具体情况.我将纯说明符视为程序员的提示,而不是与逻辑相关.它告诉你 - 程序员 - 你应该实现该方法.基类是否具有实现并不重要.

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

并不是的.你说派生的非抽象类必须覆盖该函数.这并不妨碍您自己实现它.