C++中3类的多态性
Polymorphism with 3 classes in C++
下面的代码打印12,但我希望它打印11。
#include <iostream>
using namespace std;
class A {
public:
virtual void f() { cout << "0" << endl; }
};
class B : public A{
public:
void f() { cout << "1" << endl; }
};
class C : public B{
public:
void f() { cout << "2" << endl; }
};
int main() {
A *pa = new B();
B *pb = new C();
pa->f();
pb->f();
}
在我的理解中,pa->f()执行B的f()函数,因为A是虚拟的,但为什么pb->f(。
此外,如果我从类A中删除"virtual",它将打印0 1,这是有意义的,因为A和B执行自己的f()函数,因为它们不是虚拟的。如果pb->f()没有受到影响,为什么它会改变,因为它只是一个改变的A?
但是,当B的f()不是虚拟的时,为什么pb->f()执行C的f(()函数呢。
因为pb
的动态类型是C
,而C::f
实际上是虚拟的。当您申报时
virtual void f();
根据§10.3/2:,在基类中,层次结构中派生类的每个其他void f()
也是虚拟的
如果虚拟成员函数vf在基类和Derived类中声明,直接或间接地从基类派生,则声明与Base::vf具有相同名称、参数类型列表(8.3.5)、cv限定符和ref-限定符(或不存在相同限定符)的成员函数vf,则Derived::vf也是虚拟的(无论是否如此声明),并且它覆盖了112Base::vf。
(重点矿井)
事实上:
class A {
public:
virtual void f() { cout << "0" << endl; }
};
class B : public A{
public:
virtual void f() { cout << "1" << endl; }
};
class C : public B{
public:
virtual void f() { cout << "2" << endl; }
};
相当于您的代码。恰好C++标准允许在这些情况下省略virtual
。
之所以会发生这种情况,是因为在子类中编写虚拟关键字是不必要的,它只是提高了可读性。
相关文章:
- 如何查找哪个类对象位于数组的特定索引上(多态性)
- 从基类调用函数的多态性
- 创建基类指针的向量并将派生类对象传递给它(多态性)
- 如何在 c++ 中使用多态性访问派生类字段?
- C++多态性:如何测试一个类是否派生自另一个基类
- 具有 3 级继承的基类shared_ptr的多态性
- C++ 多态性:如果派生类中的虚函数在基类中声明了常量,是否需要将其声明为常量
- 在同时处理基类的多个指针时如何处理多态性?
- 如果基类指针无法访问派生类成员函数,那么多态性有什么方便的呢?
- C++模板方法重载和具有多态性的类访问
- 没有新成员的模板多态性派生类的大小
- 从具有多态性的类中检索数据
- 多态性:通过类文本或对象访问静态成员
- c++多态性:基类的上转换/下转换和容器,缺少数据
- C++多态性模板类:调用基类方法而不是派生类
- C++中的多态性和类抽象实例
- 多态性:实例类
- c++中多态性基类和继承类实例化的问题
- 多态性基类指针
- C++ 多态性 - 继承类的映射