我刚刚惊讶地发现以下是合法的 C++
struct A {
void foo(int) const = 0; // pure virtual
// ...
};
void A::foo(int) const { /* ... */ }
什么是合理的用例?即什么时候会A::foo被调用,为什么这是正确/最好的实现?C++03 和 C++11 之间有什么区别吗?
好的,以前有一个具有相同意图的问题(我没有找到)。但是那是 C++11 之前的版本。所以我的最后一个问题仍然有效。
我刚刚惊讶地发现以下是合法的 C++
struct A {
void foo(int) const = 0; // pure virtual
// ...
};
void A::foo(int) const { /* ... */ }
什么是合理的用例?即什么时候会A::foo被调用,为什么这是正确/最好的实现?C++03 和 C++11 之间有什么区别吗?
好的,以前有一个具有相同意图的问题(我没有找到)。但是那是 C++11 之前的版本。所以我的最后一个问题仍然有效。
什么是合理的用例?
如果该函数具有合理的默认实现,或者与基类相关的任何内容的部分实现,但您仍想强制派生类覆盖它,那么这是放置它的好地方。
此外,如评论中所述,您可能希望强制没有纯虚函数的类是抽象的。您可以通过将析构函数设为纯虚拟来做到这一点;但是析构函数必须有一个主体,无论它是否是纯虚拟的。
什么时候会
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 之间有什么区别吗?
不。
规范的用例是通过提供纯虚拟析构函数来将类标记为抽象——它必须有一个实现。
自 C++98 之前以来,这一直是规则。
当然是合法的。
纯虚函数意味着它声明的那个类的实例不能被实例化,而不是它不能有一个实现。
例如,它就像 C# 中的接口。
它提供了哪些机会?
1.客户端可以使用默认实现。
2.具有纯虚析构函数的类不再引发链接器错误
(当您将删除应用于指向基类的指针时:调用派生类的析构函数,然后调用基类的析构函数,如果您省略实现 - 链接器将引发错误)。
参考: Scott Myers 所著的《Effective C++》一书中深入描述了纯虚方法实现的必要性