深入多态—虚表指针
来源:互联网 发布:淼说大数据精准营销 编辑:程序博客网 时间:2024/06/05 22:45
上一篇就多态做了简单的介绍,但还是对多态的运行很迷,那我们就来虚函数内部是怎么操作的?
(一)单继承中的虚函数(无虚拟继承)
#include<iostream>using namespace std;class A{public: virtual void Funtest1() { cout<<"A::Funtest1()"<<endl; } virtual void Funtest2() { cout<<"A::Funtest2()"<<endl; } int _a;};class B:public A{public: virtual void Funtest1()//实现函数重写 { cout<<"B::Funtest1()"<<endl; } virtual void FunTest3() { cout<<"B::FunTest3()"<<endl; } int _b;};void Fun(){ cout<<sizeof(B)<<endl; //12 A a; B b; a._a=1; b._a=2; b._b=3;}int main(){ Fun(); system("pause"); return 0;}
分析如下:
注:单继承通常通过在每个对象内包含一个vptr指针来实现虚拟函数,vptr指针指向一个叫做vtbl的函数指针向量(称为虚拟函数表,也叫V表)。虚函数按照其声明顺序存在于虚表中。
为了验证我们上面所分析的准确无误,下面定义一个Printv函数,打印虚表所指向的函数~
typedef void (*pFunc)();//定义一个函数指针类型
其中void (*pFunc)();//是函数指针变量
typedef void (*pFunc)();void Printv(A& a)//用来打印虚表所指向的函数{ pFunc* c=(pFunc*)(*(int*)&a); //定义一个函数指针 while(*c) { (*c)(); c++; }}
运行结果:
说明前面的分析无误
(二)单继承中的虚函数(有虚拟继承)
using namespace std;typedef void (*pFunc)();class A{public: virtual void Funtest1() { cout<<"A::Funtest1()"<<endl; } virtual void Funtest2() { cout<<"A::Funtest2()"<<endl; } int _a;};class B:virtual public A{public: virtual void Funtest1()//实现函数重写 { cout<<"B::Funtest1()"<<endl; } virtual void FunTest3() { cout<<"B::FunTest3()"<<endl; } int _b;};void Printv(B& b){ pFunc* c=(pFunc*)(*(int*)&b); while(*c) { (*c)(); c++; }}void Fun(){ cout<<sizeof(B)<<endl;//20 为什么呢? A a; B b; a._a=1; b._a=2; b._b=3; Printv(b);}int main(){ Fun(); system("pause"); return 0;}为什么只加了个虚拟继承,派生类的大小就变成了20呢?看内存观变化:
(三)多继承(无虚拟继承)
class A{public: virtual void Funtest1() { cout<<"A::Funtest1()"<<endl; } virtual void Funtest2() { cout<<"A::Funtest2()"<<endl; } int _a;};class B{public: virtual void FunTest3() { cout<<"B::FunTest3()"<<endl; } virtual void FunTest4() { cout<<"B::FunTest4()"<<endl; } int _b;};class C: public A, public B{public: virtual void Funtest1()//实现函数重写 { cout<<"C::Funtest1()"<<endl; } virtual void FunTest3() { cout<<"C::FunTest3()"<<endl; } virtual void FunTest5() { cout<<"C::FunTest5()"<<endl; } int _c;};void Fun(){ cout<<sizeof(C)<<endl; A a; B b; C c; a._a=1; b._b=2; c._a=3; c._b=4; c._c=5;}int main(){ Fun(); system("pause"); return 0;}
派生类内存分布:
(四)菱形继承
using namespace std;typedef void (*pFunc)();class A{public: virtual void Funtest1() { cout<<"A::Funtest1()"<<endl; } virtual void Funtest2() { cout<<"A::Funtest2()"<<endl; } int _a;};class B:virtual public A{public: virtual void FunTest1() { cout<<"B::FunTest1()"<<endl; } virtual void FunTest3() { cout<<"B::FunTest3()"<<endl; } int _b;};class C:virtual public A{public: virtual void Funtest2()//实现函数重写 { cout<<"C::Funtest2()"<<endl; } virtual void FunTest4() { cout<<"C::FunTest4()"<<endl; } int _c;};class D: public B,public C{public: virtual void Funtest1()//实现函数重写 { cout<<"D::Funtest1()"<<endl; } virtual void FunTest3() { cout<<"D::FunTest3()"<<endl; } virtual void FunTest4() { cout<<"D::FunTest4()"<<endl; } virtual void FunTest5() { cout<<"D::FunTest5()"<<endl; } int _d;};void Fun(){ cout<<sizeof(D)<<endl; //36 具体为什么看图解 D d; d._a=1; d._b=2; d._c=3; d._d=4;}int main(){ Fun(); system("pause"); return 0;}
D模型分析
阅读全文
0 0
- 深入多态—虚表指针
- 虚函数指针深入理解
- 深入探索C++对象模型--指针类型 & 多态机制
- 深入剖析C++多态、VPTR指针、虚函数表
- 深入指针
- 深入指针
- 指针深入
- 深入理解 C++ 指针(十)---指针与链表问题
- 深入理解指针的指针
- 深入理解指针—>指针函数与函数指针的区别
- C++ 深入了解 函数, 虚函数, 单继承,多继承,指针,引用。
- 《步步深入委托》——为委托追加多个方法指针的原理
- 深入C++指针(1)
- 深入探讨this指针
- 深入探讨this指针
- 深入剖析指针
- 深入理解指针
- 深入了解指针
- python如何将字符串里有数字和文字怎么提取数字
- [C#]读取当前项目中的图片Image.FromFile
- 读《How Tomcat Works》随记1
- HDOJ2060_Snooker
- python高效编程技巧13(如何在线程之间实现事件通知)
- 深入多态—虚表指针
- 九九乘法表
- VMware Vsphere 6.0安装部署 (一) 总体部署架构
- Aspen中物性方法选择
- 处理大数字精确精度BigDecimal计算
- Java之MySQL数据库连接--JDBC驱动代码封装
- zookeeper 使用service管理并开机自启动
- hdu 1561(树形dp)(背包dp)
- 瑞利、莱斯分布与窄带过程