C++ 多态性 -- 虚函数表(2)
2018-03-16 14:39
225 查看
2018-03-15 创建人:Ruo_Xiao 开发环境:VS2010 邮箱:xclsoftware@163.com 参考链接:http://blog.csdn.net/haoel/article/details/1948051/ 上文链接:http://blog.csdn.net/itworld123/article/details/79578014
一、多重继承 – 无覆盖
#include "stdafx.h" #include <iostream> using namespace std; class Father_1 { public: virtual void F_Say_1_1() { cout << "Father Say 11" << endl; } virtual void F_Say_1_2() { cout << "Father Say 12" << endl; } virtual void F_Say_1_3() { cout << "Father Say 13" << endl; } }; class Father_2 { public: virtual void F_Say_2_1() { cout << "Father Say 21" << endl; } virtual void F_Say_2_2() { cout << "Father Say 22" << endl; } }; class Father_3 { public: virtual void F_Say_3_1() { cout << "Father Say 31" << endl; } }; class Son:public Father_1,public Father_2,public Father_3 { public: virtual void S_Say_1() { cout << "Son Say 1" << endl; } virtual void S_Say_2() { cout << "Son Say 2" << endl; } virtual void S_Say_3() { cout << < 4000 span class="hljs-string">"Son Say 3" << endl; } }; typedef void(*Fun)(void); int main() { Son S; Fun pFun_1 = NULL; Fun pFun_2 = NULL; Fun pFun_3 = NULL; Fun pFun_4 = NULL; Fun pFun_5 = NULL; Fun pFun_6 = NULL; Fun pFun_7 = NULL; Fun pFun_8 = NULL; Fun pFun_9 = NULL; cout << "虚函数表地址:" << (int *)(&S) << endl; cout << "虚函数表 — 第一个函数地址:" << (int*)*(int*)(&S) << endl; pFun_1 = (Fun)*((int *) *(int *)(&S)+0); pFun_2 = (Fun)*((int *) *(int *)(&S)+1); pFun_3 = (Fun)*((int *) *(int *)(&S)+2); pFun_4 = (Fun)*((int *) *(int *)(&S)+3); pFun_5 = (Fun)*((int *) *(int *)(&S)+4); pFun_6 = (Fun)*((int *) *(int *)(&S)+5); pFun_7 = (Fun)*((int *) *(int *)(&S)+7); pFun_8 = (Fun)*((int *) *(int *)(&S)+8); pFun_9 = (Fun)*((int *) *(int *)(&S)+10); cout<<"Father_1和Son 虚表"<<endl; pFun_1(); pFun_2(); pFun_3(); pFun_4(); pFun_5(); pFun_6(); cout<<endl; cout<<"Father_2 虚表"<<endl; pFun_7(); pFun_8(); cout<<endl; cout<<"Father_3 虚表"<<endl; pFun_9(); cin.get(); }
结果:
由上述结果可知:
1、子类的虚表中会保留所有的父类的虚表,其排布顺序和继承的顺序相同。
2、子类的虚函数会跟在第一个父类的虚表的后面。
3、上述栗子中虚表的排布如下图所示:
(1)图片中,蓝色代表父类Father_1,绿色代表父类Father_2,紫色代表父类Father_3。
(2)各个父类的虚表是连续的,并且以各自的结束符“NULL”为标志。
4、有上述可知,代码中没有“+6”和“+9”,因为二者对应的是NULL。
二、多重继承 – 有覆盖
#include "stdafx.h" #include <iostream> using namespace std; class Father_1 { public: virtual void F_Say_1() { cout << "Father Say 1" << endl; } virtual void F_Say_1_2() { cout << "Father Say 12" << endl; } virtual void F_Say_1_3() { cout << "Father Say 13" << endl; } }; class Father_2 { public: virtual void F_Say_1() { cout << "Father Say 1" << endl; } virtual void F_Say_2_2() { cout << "Father Say 22" << endl; } }; class Father_3 { public: virtual void F_Say_1() { cout << "Father Say 1" << endl; } }; class Son:public Father_1,public Father_2,public Father_3 { public: virtual void F_Say_1() { cout << "Son Say 1" << endl; } virtual void F_Say_1_2() { cout << "Son Say 2" << endl; } virtual void F_Say_2_2() { cout << "Son Say 3" << endl; } }; typedef void(*Fun)(void); int main() { Son S; Fun pFun_1 = NULL; Fun pFun_2 = NULL; Fun pFun_3 = NULL; Fun pFun_4 = NULL; Fun pFun_5 = NULL; Fun pFun_6 = NULL; cout << "虚函数表地址:" << (int *)(&S) << endl; cout << "虚函数表 — 第一个函数地址:" << (int*)*(int*)(&S) << endl; pFun_1 = (Fun)*((int *) *(int *)(&S)+0); pFun_2 = (Fun)*((int *) *(int *)(&S)+1); pFun_3 = (Fun)*((int *) *(int *)(&S)+2); pFun_4 = (Fun)*((int *) *(int *)(&S)+4); pFun_5 = (Fun)*((int *) *(int *)(&S)+5); pFun_6 = (Fun)*((int *) *(int *)(&S)+7); cout<<"Father_1和Son 虚表"<<endl; pFun_1(); pFun_2(); pFun_3(); cout<<endl; cout<<"Father_2 虚表"<<endl; pFun_4(); pFun_5(); cout<<endl; cout<<"Father_3 虚表"<<endl; pFun_6(); cin.get(); }
结果:
有上述结果可知:若多个父类中有相同名字的虚函数,而且子类重写的该虚函数,则在虚表中,所有的父类的该虚函数均被覆盖。
(SAW:Game Over!)
相关文章推荐
- C++多态性分析之虚函数表
- C++多态性、虚函数
- 细谈C++多态性的"动"与"静"
- C++虚函数表解析
- c++ primer学习之-----C++ 中的多态性
- 详谈C++虚函数表那回事(一般继承关系)
- C++的虚函数表
- C++ 虚函数表解析
- C++ 虚函数表解析
- C++虚函数与C++虚函数表
- C++中的虚函数表(转)
- c++ 虚函数 多态性 (一)
- C++虚函数表解析
- C++ 多态性(3) 运算符重载2
- C++多态性与虚函数
- C++虚函数表解析(转)
- C++ vptr vtbl (C++虚表指针,虚函数表,虚函数的实现)很多人都喜欢问这个,写下吧。
- C++虚函数表解析(转)
- c++ 继承类强制转换时的虚函数表工作原理
- C++ 由虚基类 虚继承 虚函数 到 虚函数表