当前位置: 首页 > news >正文

手机网站建设的教程视频南昌地宝网租房信息网

手机网站建设的教程视频,南昌地宝网租房信息网,西安景点排名前十,海外红人营销推广vtpr的位置: 为了支持多态,C引入了vtpr和vtable这两个概念.对于每个有虚函数的类,C都会为其生成一个vtable,并在类中添加一个隐含的数据成员vptr. 对于vptr在对象中的位置,跟类的数据成员的布局一样,C标准里面并没有做出任何的规定.但是对于特定的编译器,我们还是可以通…vtpr的位置:        为了支持多态,C引入了vtpr和vtable这两个概念.对于每个有虚函数的类,C都会为其生成一个vtable,并在类中添加一个隐含的数据成员vptr. 对于vptr在对象中的位置,跟类的数据成员的布局一样,C标准里面并没有做出任何的规定.但是对于特定的编译器,我们还是可以通过研究C对象的内存布局来确定vtpr到底是放在哪里.       下面我们通过分析C对象的内存布局,来寻找vptr的位置.在开始讨论之前我们先提供一个模板函数void PrintLayout(T const obj),该函数用于打印obj所在内存的内容,下面是该函数的实现: PrintLayout.hxx#pragma once #include iostream #include iomanip #include ReinterpretCast.hxxtemplatetypename T void PrintLayout(T const obj) {int * pObj ReinterpretCastint*(obj);for (int i 0; isizeof(obj)/sizeof(int);i){std::coutstd::setw(10) pObj[i]std::endl;} }接下来通过代码来分析一下在C里,在没有继承,单继承,多继承以及虚继承等情况下对象的内存布局,下面是示例代码,为了减少代码量,我们将类的所有数据成员设为public的,在这里我们用struct来代替class: //main.cpp#include iostream #include PrintLayout.hxx #include typeinfo using namespace std;struct NoVirtualMemFunc {int Func1(int a,int b){cout__FUNCTION__/tm_iDatam_iData/taa/tbbendl;return 0;}int Func2(int a,int b){cout__FUNCTION__/tm_iDatam_iData/taa/tbbendl;return 0;}int m_iData; }; struct Base1 {virtual int Base1Func1(int a,int b){cout__FUNCTION__/tm_iDatam_iData/taa/tbbendl;return 0;}virtual int Base1Func2(int a,int b){cout__FUNCTION__/tm_iDatam_iData/taa/tbbendl;return 0;}int m_iData; }; struct Base2 {virtual int Base2Func1(int a,int b){cout__FUNCTION__/tm_iDatam_iData/taa/tbbendl;return 0;}virtual int Base2Func2(int a,int b){cout__FUNCTION__/tm_iDatam_iData/taa/tbbendl;return 0;}int m_iData; };struct D1:public Base1 {virtual int D1Func(int a,int b){cout__FUNCTION__/tm_iDatam_iData/taa/tbbendl;return 0;}int m_iData; }; struct D:public Base1,public Base2 {virtual int DFunc(int a,int b){cout__FUNCTION__/tm_iDatam_iData/taa/tbbendl;return 0;}int m_iData; };struct VD1:public virtual Base1 {virtual int VD1Func(int a,int b){cout__FUNCTION__/tm_iDatam_iData/taa/tbbendl;return 0;}int m_iData; }; struct VD2:public virtual Base1 {virtual int D2Func(int a,int b){cout__FUNCTION__/tm_iDatam_iData/taa/tbbendl;return 0;}int m_iData; }; struct VD:public VD1,public VD2 {int m_iData; };templatetypename T void PRINT_LAYOUT(T const obj) {coutThe layout of typeid(obj).name()----------------endl;PrintLayout(obj);coutendl; } int main(int argc, char* argv[]) {//没有继承,没有虚函数的情况{NoVirtualMemFunc obj;obj.m_iData 100;PRINT_LAYOUT(obj);}//没有继承,有虚函数的情况{Base1 obj;obj.m_iData 100;PRINT_LAYOUT(obj);}//单继承{D1 obj;obj.Base1::m_iData 100;obj.m_iData 200;PRINT_LAYOUT(obj);}//多继承{D obj;obj.Base1::m_iData 100;obj.Base2::m_iData 200;obj.m_iData 300;PRINT_LAYOUT(obj);}//虚拟继承{VD1 obj;obj.Base1::m_iData 100;obj.m_iData 200;PRINT_LAYOUT(obj);}//棱形继承{VD obj;obj.Base1::m_iData 100;obj.VD1::m_iData 200;obj.VD2::m_iData 300;obj.m_iData 500;PRINT_LAYOUT(obj);}return 0; }//输出 /* The layout of struct NoVirtualMemFunc----------------100The layout of struct Base1----------------4294656100The layout of struct D1----------------4294740100200The layout of struct D----------------42948001004294776200300The layout of struct VD1----------------429487642948882004294864100The layout of struct VD----------------42949444294968200429493242949523005004294920100请按任意键继续. . .对于有虚表的函数,从上面的输出我们可以得到以下结论, 1.没有继承情况,vptr存放在对象的开始位置,以下是Base1的内存布局 vptr : 4294656 m_iData :100 2.单继承的情况下,对象只有一个vptr,它存放在对象的开始位置,派生类子对象在父类子对象的最后面,以下是D1的内存布局 vptr : 4294740 B1:: m_iData : 100 B2:: m_iData :200 3.多继承情况下,对象会为每个有虚函数的父类子对象提供一个vptr,派生类子对象在所有父类子对象的最后面,所有父类子对象按照声明顺序排列,以下是D的内存布局 B1::vptr : 4294800 B1::m_iData :100 B2::vptr : 4294776 B2::m_iData :200 D::m_iData :300 4. 虚拟继承情况下,虚父类子对象会放在派生类子对象之后,派生类子对象的第一个位置存放着一个vptr,虚拟子类子对象也会保存一个vptr,以下是VD1的内存布局 VD1::vptr :4294876  Unknown : 4294888 VD1::m_iData : 200 B1::vptr :4294864 B1::m_iData :100 5. 棱形继承的情况下,非虚基类子对象在派生类子对象前面,并按照声明顺序排列,虚基类子对象在派生类子对象后面 VD1::vptr :        4294944 VD1::Unknown : 4294968 VD1::m_iData :  200 VD2::vptr :    4   294932 VD2::Unknown : 4294952 VD2::m_iData : 300 VD::m_iData : 500 B1::vptr :       4294920 B1::m_iData :  100 接下来我们将通过代码来验证前面结论的准确性.下面的代码具有一定的局限性.在调试以下代码的时候,对虚拟继承遇到了以下几个让我迷惑的问题: 1.对于虚拟继承,函数指针的大小为12 2.用vtable里面的指针调用,this不能正确传进去 3.如果派生类的虚拟函数多于1个,则会crash //main.cpp#include iostream #include GetVptr.hxx #include typeinfo using namespace std;struct NoVirtualMemFunc {int Func1(int a,int b){cout__FUNCTION__/tm_iDatam_iData/taa/tbbendl;return 0;}int Func2(int a,int b){cout__FUNCTION__/tm_iDatam_iData/taa/tbbendl;return 0;}int m_iData; }; struct Base1 {virtual int Base1Func1(int a,int b){cout__FUNCTION__/tm_iDatam_iData/taa/tbbendl;return 0;}virtual int Base1Func2(int a,int b){cout__FUNCTION__/tm_iDatam_iData/taa/tbbendl;return 0;}int m_iData; }; struct Base2 {virtual int Base2Func1(int a,int b){cout__FUNCTION__/tm_iDatam_iData/taa/tbbendl;return 0;}virtual int Base2Func2(int a,int b){cout__FUNCTION__/tm_iDatam_iData/taa/tbbendl;return 0;}int m_iData; };struct D1:public Base1 {virtual int D1Func(int a,int b){cout__FUNCTION__/tm_iDatam_iData/taa/tbbendl;return 0;}int m_iData; }; struct D:public Base1,public Base2 {virtual int DFunc(int a,int b){cout__FUNCTION__/tm_iDatam_iData/taa/tbbendl;return 0;}int m_iData; };struct VD1:public virtual Base1 {virtual int VD1Func(int a,int b){cout__FUNCTION__/tm_iDatam_iData/taa/tbbendl;return 0;}int m_iData; }; struct VD2:public virtual Base1 {virtual int D2Func(int a,int b){cout__FUNCTION__/tm_iDatam_iData/taa/tbbendl;return 0;}int m_iData; }; struct VD:public VD1,public VD2 {int m_iData; };templateclass T struct MemFuncT {typedef int (T::* T_MemFuncT)(int,int);typedef int (T::* T_MemDataT); }; templateclass C void CallMemFunc(int iFuncNum,int (C::**vptr)(int,int),C obj,int a 500,int b 600) {for (int i 0;iiFuncNum;i){//coutReinterpretCastvoid*(vptr[i]) ;(obj.*vptr[i])(a,b);}coutendl; } int main(int argc, char* argv[]) {//没有继承,有虚函数的情况{cout//没有继承,有虚函数的情况endl;Base1 obj;obj.m_iData 100;MemFuncTBase1::T_MemFuncT * vptr ReinterpretCastMemFuncTBase1::T_MemFuncT *(GetVptr(obj));CallMemFunc(2,vptr,obj);}//单继承{cout//单继承endl;D1 obj;obj.Base1::m_iData 100;obj.m_iData 200;MemFuncTD1::T_MemFuncT * vptr ReinterpretCastMemFuncTD1::T_MemFuncT *(GetVptr(obj));CallMemFunc(3,vptr,obj);}//多继承{cout//多继承endl;D obj;obj.Base1::m_iData 100;obj.Base2::m_iData 200;obj.m_iData 300;Base1 objB1 obj;MemFuncTBase1::T_MemFuncT * vptr ReinterpretCastMemFuncTBase1::T_MemFuncT *(GetVptr(obj));CallMemFunc(3,vptr,objB1);Base2 objB2 obj;MemFuncTBase2::T_MemFuncT * vptrB2 ReinterpretCastMemFuncTBase2::T_MemFuncT *(GetVptr(objB2));CallMemFunc(2,vptrB2,objB2);}#if 1//虚拟继承{cout//虚拟继承endl;VD1 obj;obj.Base1::m_iData 100;obj.m_iData 200;MemFuncTVD1::T_MemFuncT * vptr ReinterpretCastMemFuncTVD1::T_MemFuncT *(GetVptr(obj));CallMemFunc(1,vptr,obj);Base1 objB1 obj ;MemFuncTBase1::T_MemFuncT * vptrB1 ReinterpretCastMemFuncTBase1::T_MemFuncT *(GetVptr(objB1));CallMemFunc(2,vptrB1,objB1);}//棱形继承{cout//棱形继承endl;VD obj;obj.Base1::m_iData 100;obj.VD1::m_iData 200;obj.VD2::m_iData 300;obj.m_iData 500;Base1 objB1 obj;MemFuncTBase1::T_MemFuncT * vptrB1 ReinterpretCastMemFuncTBase1::T_MemFuncT *(GetVptr(objB1));CallMemFunc(2,vptrB1,objB1);VD1 objVD1 obj;MemFuncTVD1::T_MemFuncT * vptrVD1 ReinterpretCastMemFuncTVD1::T_MemFuncT *(GetVptr(objVD1));CallMemFunc(1,vptrVD1,objVD1);VD2 objVD2 obj;MemFuncTVD2::T_MemFuncT * vptrVD2 ReinterpretCastMemFuncTVD2::T_MemFuncT *(GetVptr(objVD2));//CallMemFunc(1,vptrVD2,objVD2);} #endifreturn 0; }//输出 /* //没有继承,有虚函数的情况 Base1::Base1Func1 m_iData100 a500 b600 Base1::Base1Func2 m_iData100 a500 b600//单继承 Base1::Base1Func1 m_iData100 a500 b600 Base1::Base1Func2 m_iData100 a500 b600 D1::D1Func m_iData200 a500 b600//多继承 Base1::Base1Func1 m_iData100 a500 b600 Base1::Base1Func2 m_iData100 a500 b600 D::DFunc m_iData300 a500 b600Base2::Base2Func1 m_iData200 a500 b600 Base2::Base2Func2 m_iData200 a500 b600//虚拟继承 VD1::VD1Func m_iData4294960 a500 b600Base1::Base1Func1 m_iData100 a500 b600 Base1::Base1Func2 m_iData100 a500 b600//棱形继承 Base1::Base1Func1 m_iData100 a500 b600 Base1::Base1Func2 m_iData100 a500 b600VD1::VD1Func m_iData4295032 a500 b600请按任意键继续. . . */
http://wiki.neutronadmin.com/news/72211/

相关文章:

  • 做网站服务器收费吗一手房哪个网站做信息效果好
  • 刷评论网站推广soho hotel 酒店 wordpress主题
  • 杭州网站设计公司电话区网站制作
  • 域名网站注册认证北京到太原
  • 大连专业做网站二级单位网站建设
  • seo案例网站公司网站制作方案
  • 行知智网站开发wordpress加载速度慢
  • 卢沟桥做网站的公司百度一下你知道
  • 广州做网站技术网站备案的幕布是什么意思
  • 有网站源码怎么上传深圳网站建设乐云seo
  • 网站页面的滑动怎么做办公室装修一般价格
  • 做网站莱芜ftp跟网络连接Wordpress
  • 外贸手机商城网站建设 深圳三合一企业网站模板
  • 网站建设有限公wordpress在线报名模块
  • 网站建设费用包括哪些内容电子商城官方网站
  • 南海网站制作公司企业网站建设要
  • 百度建网站多少钱宁波开发网络推广平台
  • 做传销网站违法wordpress auto highslide
  • 中山营销型网站设计沈阳想做网站
  • 网络推广哪个网站好品牌网站建设3小蝌蚪
  • 外贸网站建设980怎样搭建电商平台
  • 网站改标题不改版 k策划方案模板
  • 安卓搭建网站购物网名昵称
  • 网页设计茶叶网站建设wordpress 自媒体模版
  • 网站的风格主要包括wordpress 4.7 暴路径
  • 整页型网站软件开发者工具
  • 西安网站建设平台网站需要证件
  • 网站建设销售技巧和话术男女做暖网站是什么样子的
  • 学做预算有网站吗芜湖网站建设优化
  • 做网站聊城企业形象网站解决方案