具有函数体的纯虚拟成员函数有什么意义?

时间:2013-08-27 13:31:08

标签: c++ pure-virtual

我只是惊讶地发现以下是合法的C ++

struct A {
  void foo(int) const = 0;  // pure virtual
  // ...
};
void A::foo(int) const { /* ... */ }

有什么明智的用例?即何时会A::foo被调用,为什么这是正确/最好的实现? C ++ 03和C ++ 11之间有什么区别吗?


好的,有一个先前的问题(我没有找到)具有相同的意图。然而那是C ++ 11之前的版本。所以我的最后一个问题仍然有效。

3 个答案:

答案 0 :(得分:4)

  

有什么明智的用例?

如果函数有一个合理的默认实现,或部分实现与基类相关的任何内容,但你仍然想强制派生类覆盖它,那么这是一个放置它的好地方。

此外,如注释中所述,您可能希望强制没有纯虚函数的类是抽象的。你可以通过使析构函数纯虚拟来做到这一点;但是析构函数必须有一个正文,无论它是否是纯虚的。

  

何时会调用A::foo

它只能被称为非虚拟的;例如:

struct B : A {
    void f(int i) const {
        A::foo(i);    // non-virtual call
        // Do the B-specific stuff
    }
};
  

为什么这是正确/最好的实施?

除了未实现的纯虚函数之外,另一种方法是为部分/默认实现创建一个新名称。

  

C ++ 03和C ++ 11之间是否存在差异?

没有

答案 1 :(得分:3)

规范用例是通过提供纯虚拟析构函数将类标记为抽象 - 必须具有实现。

这是自C ++ 98之前的规则。

答案 2 :(得分:1)

当然是合法的。 纯虚函数意味着它声明的那个类的实例不能被实例化,而不是它没有实现。
例如,它就像C#中的界面一样。

它提供了哪些机会?
1.客户可以使用默认实施 2.具有纯虚析构函数的类不再引发链接器错误 (当你将delete应用于指向基类的指针时:调用派生类的析构函数,然后调用基类的析构函数,如果省略实现 - 链接器将引发错误)。

参考文献:纯虚方法实现的需求在Scott Myers的“Effective C ++”一书中有详细描述

相关问题