当前位置: 首页 > 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://www.sadfv.cn/news/72211/

相关文章:

  • 北京 集团公司网站建设大淘客做网站视频
  • 芜湖市建设工程质量监督站官方网站安徽省铜陵市建设银行网站
  • 南昌网站做wordpress卡核销
  • 微信怎样将网站的内容做备案 网站 收录
  • 门户网站建设 突出服务装潢设计公司排行
  • 公司网站建设文案wordpress怎么修改栏目标题
  • 网站可以用PS设计吗2023免费网站推广大全
  • 响应式网站宽度wordpress 标签页
  • spring可以做多大的网站做计划网站
  • 乡镇信息公开网站建设制度电脑系统7怎么打开wordpress
  • 济南网站建设公司 推荐行知科技网站根目录在哪里
  • 网站正在建设中空白模板效果图网址
  • 用旧手机做网站做网站后台运营这个工作怎么样
  • 织梦系统做网站商业网站首页怎么做
  • 包头微网站开发seo排名优化公司价格
  • 国外做健康的网站什么是主页
  • 布吉网站建设哪家便宜竞价网站做招商加盟可以不备案吗
  • 养生网站设计一个专门做试题的网站
  • 南阳网站制作公司东莞网站建设 手机壳
  • 简单网站建设优化.net网站开发实训体会
  • 网站建设需求确认书徐州网站制作费用
  • 网站平台开发报价表怎么做国外做外贸哪个网站好些
  • 淄博亿泰网站建设推广app开发公司有哪些
  • 上海闵行建网站公司海尔网站建设不足之处
  • 电子商务网站建设的展望Wordpress图床对接阿里云
  • 北京齐力众信网站建设做自媒体的网站名字
  • 网站建站平台php网站开发视频教学
  • 用织梦怎么修改网站首页商品顺序怎么让别人访问我建的网站
  • wordpress建电影网站wordpress简约模板下载
  • 微信怎么建小网站邯郸网站优化建设