具有函数体的纯虚拟成员函数的意义何在
What is the point of a pure-virtual member function with function body?
我刚刚惊讶地发现以下是合法的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.具有纯虚拟析构函数的类不再引发链接器错误(当您将delete应用于指向基类的指针时:将调用派生类的析构函数,并且在调用基类的析构因子之后,如果您提交实现-链接器将引发错误)。
参考文献:在Scott Myers 的《有效C++》一书中深入描述了在纯虚拟方法中实现的需求
相关文章:
- 虚拟成员函数的定义是否强制在同一转换单元中动态初始化静态数据成员?
- 将C++子类成员函数(虚拟实现)传递给 C 类型函数指针
- 如果我必须覆盖非虚拟成员函数怎么办
- 非虚拟成员函数是否可以使用模板参数?
- 如何将已实现的虚拟成员函数作为参数传递
- 睡眠影响 std::thread 调用哪个虚拟成员函数?
- boost::bind 无法绑定到纯虚拟基类中定义的非静态函数模板成员类型
- GTEST:嘲笑非虚拟成员函数
- 虚拟和非虚拟成员函数的调用方式有什么区别?
- 默认情况下是虚拟成员函数
- 为什么在已删除的指针上调用非虚拟成员函数是未定义的行为
- C++标准是否保证了没有虚拟成员函数的类类型的大小
- C++合成的move构造函数如何受到volatile和虚拟成员的影响
- 在非构造"object"上调用非虚拟成员函数是否定义良好?
- 指向虚拟成员函数的指针是否具有可比性
- 通过指针访问私有虚拟成员函数
- 尝试在 QLabel 上绘画失败(无法在没有对象的情况下调用成员函数"虚拟无效 QLabel::p aintEvent(QPaintEvent*)")
- 如何获取"direct"函数指向虚拟成员函数的指针?
- 将 decltype 与虚拟成员函数指针一起使用
- 如何使用基类指针调用派生类非虚拟成员函数,而无需类型转换和使用多态性