1

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

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

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


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

4

3 回答 3

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 之间有什么区别吗?

不。

于 2013-08-27T13:38:13.503 回答
3

规范的用例是通过提供纯虚拟析构函数来将类标记为抽象——它必须有一个实现。

自 C++98 之前以来,这一直是规则。

于 2013-08-27T13:33:33.627 回答
1

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

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

参考: Scott Myers 所著的《Effective C++》一书中深入描述了纯虚方法实现的必要性

于 2013-08-27T13:48:15.583 回答