0%
虚函数与多态
- 常规多态:
virtual
+ 指针/引用
- 代码中的
test1()
、test2()
- 下图中
a,an,ap,b
的类型,指针/引用记录了类型
B
test2()
:指针/引用会为派生类新加一个虚函数表
- 是否多态看的还是虚函数表是哪一个(而不是只看形式上是不是指针)
- 基类和派生类都只有一个虚表
- 不含有成员变量的前提下:
sizeof(A) = sizeof(B) = sizeof(void*)
1 2 3 4 5
| B b; A a = b; (&a)->a_v(); a.a_v();
|
- 派生类如果没有实现基函数的
virtual
函数,则多态时会调用基类的 virtual
函数
- 如果基类虚函数中调用了常规函数,但是常规函数在派生类中被覆盖
- 此时派生类调用这个虚函数时,内部调用的是父类的常规函数
- 代码中的
test3()
- 析构函数建议定义为多态
- 虚函数表一个类一个
虚函数表
- 派生类复制父类的虚函数表,然后修改 override 的,然后在最后加上自己的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class A { public: virtual void a_v() { OUTPUT; } virtual void b_v() { OUTPUT; } };
class B : public A { public: virtual void a_v() override { OUTPUT; } virtual void c_v() { OUTPUT; } };
class C : public B { public: virtual void d_v() { OUTPUT; } };
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| virtual table address: 00007FF7C453BD48 virtual function 0 --> 00007FF7C453141F --> function: A::a_v virtual function 1 --> 00007FF7C453134D --> function: A::b_v
virtual table address: 00007FF7C453BD88 virtual function 0 --> 00007FF7C4531311 --> function: B::a_v virtual function 1 --> 00007FF7C453134D --> function: A::b_v virtual function 2 --> 00007FF7C453107D --> function: B::c_v
virtual table address: 00007FF7C453BDC0 virtual function 0 --> 00007FF7C4531311 --> function: B::a_v virtual function 1 --> 00007FF7C453134D --> function: A::b_v virtual function 2 --> 00007FF7C453107D --> function: B::c_v virtual function 3 --> 00007FF7C4531451 --> function: C::d_v
|