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

时间:2012-10-16 15:52:50

标签: c++ class polymorphism virtual-functions

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

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

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

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

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

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

5 个答案:

答案 0 :(得分:10)

  

“我们说该函数不能对声明此纯虚函数的类有任何定义。”

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

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

A::~A() {}

struct B : A {};

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

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

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

void A::foo() {}

struct B : A {};

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

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

在析构函数的特定情况下,具有,因为在销毁子类实例时it will be called automatically。尝试使用没有定义的纯虚析构函数实例化类的子类的程序将不会传递链接器。

答案 1 :(得分:6)

使其纯粹强制派生(非抽象)类来实现自己的。

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

答案 2 :(得分:5)

有2例。

纯虚拟析构函数

此案件由标准专门处理。

12.4析构函数[class.dtor]

  

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

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

纯虚方法

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

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

  

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

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

答案 3 :(得分:2)

对于所有纯虚拟函数,这不是必需的。一点也不。

这样,派生类仍然会被强制覆盖实现,但是基类中会有一个默认实现,以防需要称之为。这就是这种情况 - 因为你正在处理析构函数:当一个派生对象被销毁时,它的析构函数被称为,它的基类析构函数也会被调用。这就是您需要A::~A实施的原因。

答案 4 :(得分:0)

通过使函数为纯虚拟,我们强制类的用户将该函数替换为派生类中的另一个函数。

仍然可以使用BaseClass::myfunction(...)

调用基类函数

现在,基类可能希望提供一些核心功能,如果选择这样做,派生类可以使用这些功能。