虚函数指针和虚函数表
虚函数表的定义
多态是由虚函数实现的,而虚函数主要是通过虚函数表(V-Table)来实现的。
如果一个类中包含虚函数(virtual修饰的函数),那么这个类就会包含一张虚函数表(vftbl),虚函数表存储的每一项是一个虚函数的地址。在一个对象的内存布局中,指向这张虚函数表的指针(vfptr)位于最前端。如下图:
![](https://img-blog.csdnimg.cn/img_convert/593bd18b68179874d437cb33a2a96325.jpeg)
一般继承(无虚函数覆盖)
对于如下UML的类:在普通继承情况,派生类没有重写基类的虚函数:
![](https://img-blog.csdnimg.cn/img_convert/8b698c4ff11d1f1d5e8604a74424cfa8.jpeg)
体现在代码上为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| #include <iostream>
using namespace std;
class Base { public: virtual void f() { cout << "Base:f()" << endl; } virtual void g() { cout << "Base:g()" << endl; } virtual void h() { cout << "Base:h()" << endl; } };
class Derive : public Base { public: virtual void f1() { cout << "Derive:f1()" << endl; } virtual void g1() { cout << "Derive:g1()" << endl; } virtual void h1() { cout << "Derive:h1()" << endl; } };
int main() { Base base; Derive derive;
}
|
使用lldb查看虚函数指针和虚函数表内容:
![](https://img-blog.csdnimg.cn/img_convert/3ffc43ada35d1514d83eee846263a4a2.png)
根据结果,可以得知其虚函数表如下图:
![](https://img-blog.csdnimg.cn/img_convert/168b6054f4cfa8047abcc4697ece654a.jpeg)
一般继承(有虚函数覆盖)
对于如下UML的类:在普通继承情况,派生类重写了基类的虚函数( f() ):
![](https://img-blog.csdnimg.cn/img_convert/6cde9cfa2653d59b5dee0dd1eff56e27.jpeg)
代码为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| #include <iostream>
using namespace std;
class Base { public: virtual void f() { cout << "Base:f()" << endl; } virtual void g() { cout << "Base:g()" << endl; } virtual void h() { cout << "Base:h()" << endl; } };
class Derive : public Base { public: virtual void f() { cout << "Derive:f()" << endl; } virtual void g1() { cout << "Derive:g1()" << endl; } virtual void h1() { cout << "Derive:h1()" << endl; } };
int main() { Base base; Derive derive;
}
|
结果为:
![](https://img-blog.csdnimg.cn/img_convert/c2e3ab6494a7bb2472a157d34371624f.png)
绘制成图,为:
![](https://img-blog.csdnimg.cn/img_convert/c47fc350ea761bb724e8243582842190.jpeg)
多重继承(无虚函数覆盖)
对于如下UML的类:在多重继承情况,派生类没有重写了基类的虚函数:
![](https://img-blog.csdnimg.cn/img_convert/73267bccfc943b3ce622723241b4b16c.jpeg)
代码为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| #include <iostream>
using namespace std;
class Base1 { public: virtual void f() { cout << "Base1:f()" << endl; } virtual void g() { cout << "Base1:g()" << endl; } virtual void h() { cout << "Base1:h()" << endl; } };
class Base2 { public: virtual void f() { cout << "Base2:f()" << endl; } virtual void g() { cout << "Base2:g()" << endl; } virtual void h() { cout << "Base2:h()" << endl; } };
class Base3 { public: virtual void f() { cout << "Base3:f()" << endl; } virtual void g() { cout << "Base3:g()" << endl; } virtual void h() { cout << "Base3:h()" << endl; } };
class Derive : public Base1, public Base2, public Base3 { public: virtual void f1() { cout << "Derive:f1()" << endl; } virtual void g1() { cout << "Derive:g1()" << endl; } };
int main() { Derive derive;
}
|
结果为:
![](https://img-blog.csdnimg.cn/img_convert/7981f59e36ad2445b061466aa521a965.png)
绘制成图,为:
![](https://img-blog.csdnimg.cn/img_convert/ca1e186bc8e2b7b35fd3743255e8f57a.jpeg)
多重继承(有虚函数覆盖)
对于如下UML的类:在多重继承情况,派生类没有重写了基类的虚函数:
![](https://img-blog.csdnimg.cn/img_convert/a1f9a775bcbbbb52db1ecf9175493cc3.jpeg)
代码为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| #include <iostream>
using namespace std;
class Base1 { public: virtual void f() { cout << "Base1:f()" << endl; } virtual void g() { cout << "Base1:g()" << endl; } virtual void h() { cout << "Base1:h()" << endl; } };
class Base2 { public: virtual void f() { cout << "Base2:f()" << endl; } virtual void g() { cout << "Base2:g()" << endl; } virtual void h() { cout << "Base2:h()" << endl; } };
class Base3 { public: virtual void f() { cout << "Base3:f()" << endl; } virtual void g() { cout << "Base3:g()" << endl; } virtual void h() { cout << "Base3:h()" << endl; } };
class Derive : public Base1, public Base2, public Base3 { public: virtual void f() { cout << "Derive:f()" << endl; } virtual void g1() { cout << "Derive:g1()" << endl; } };
int main() { Derive derive;
}
|
结果为:
![](https://img-blog.csdnimg.cn/img_convert/9ee968644c8d55f73e596f54a0613d84.png)
绘制成图,为:
![](https://img-blog.csdnimg.cn/img_convert/e841543e8c623bcbf6ab376f6117fb9a.jpeg)