我只是惊讶地发现以下是合法的C ++
struct A {
void foo(int) const = 0; // pure virtual
// ...
};
void A::foo(int) const { /* ... */ }
有什么明智的用例?即何时会A::foo
被调用,为什么这是正确/最好的实现? C ++ 03和C ++ 11之间有什么区别吗?
好的,有一个先前的问题(我没有找到)具有相同的意图。然而那是C ++ 11之前的版本。所以我的最后一个问题仍然有效。
答案 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 ++”一书中有详细描述