2013亚马逊面试题--虚继承的内存模型分析.pdf_第1页
2013亚马逊面试题--虚继承的内存模型分析.pdf_第2页
2013亚马逊面试题--虚继承的内存模型分析.pdf_第3页
2013亚马逊面试题--虚继承的内存模型分析.pdf_第4页
2013亚马逊面试题--虚继承的内存模型分析.pdf_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

本文由西安白癜风医院 本文由西安白癜风医院 2013 亚马逊面试题亚马逊面试题 虚继承的内存模型分析虚继承的内存模型分析 前两天逛论坛的时候 看到一个有关虚继承中类的大小 亚马逊二面的面试题 帖子 看了下还真不会 觉得慢慢研究下 大概搞明白为什么了 将自己的一点结果跟大家分享下 吧 欢迎拍板 我的上一篇博客也虚继承有相关解释 这里就先从以下几个点进行说明吧 虚继承和虚基类 vs2010 下的 cl 命令 内存模型 虚继承和虚基类虚继承和虚基类 虚继承 在继承定义中包含了 virtual 关键字的继承关系 虚基类 在虚继承体系中的通过 virtual 继承而来的基类 需要注意的是 class CSubClass public virtual CBase 其中 CBase 称之为 CSubClass 的虚基类 而不是说 CBase 就是个虚基类 因为 CBase 还可以不不是虚继承体系中的基类 vs2010 下的下的 cl 命令命令 微软的 VS2010 提供了一个新的选项 给用户显示 C 对象在内存中的布局 这个选项 就是 cpp view plaincopyprint 1 d1reportSingleClassLayout 具体使用方法如下 在写好相应的 cpp 文件之后 需要启动 VS2010 的命令行工具 Visual Studio 2010Command Prompt 切换到 cpp 文件所在目录之后 输入如下的命令 cpp view plaincopyprint 1 cl filename cpp d1reportSingleClassLayout className cl 当然就是 MS 的编译器 filename cpp 就是你所想要查看的 class 所在的 cpp 文件 class 定义在头文件也没关系 还是只要编译 cpp 文件即可 而你需要在最后加上 className 也就是你需要查看的 class 的类名 举例 test cpp 文件代码如下 cpp view plaincopyprint 1 include 2 using namespace std 3 本文由西安白癜风医院 本文由西安白癜风医院 4 class Base 5 6 public 7 int a 8 virtual void fcn 9 10 11 class Derived public Base 12 13 public 14 virtual void fcn2 15 private 16 int d 17 void fcn3 18 19 20 int main 21 22 查看 Derived 这个类的对象在内存中的布局 那么就可以用下面的命令行 cpp view plaincopyprint 1 cl Test cpp d1reportSingleClassLayoutDerived 结果显示如下 本文由西安白癜风医院 本文由西安白癜风医院 可以看到 class Derived 的对象的内存布局 在派生类对象的开始包含了基类 Base 的 对象 其中有一个虚表指针 指向的就是下面的 Derived vftable virtual function table 表中包含了 Derived 类中所有的虚函数 内存模型内存模型 在这一小节里面我主要从他面试的几个题目中来谈谈虚继承的内存模型 代码一 代码一 cpp view plaincopyprint 1 class A 2 3 virtual void a 4 5 6 7 class A1 8 9 virtual void a 10 11 12 13 14 class B public A virtual public A1 15 16 17 void main 18 19 cout sizeof A sizeof A endl 20 cout sizeof A1 sizeof A1 endl 21 cout sizeof B sizeof B endl 22 输出结果是 在命令行中输入 cpp view plaincopyprint 本文由西安白癜风医院 本文由西安白癜风医院 1 cl test cpp d1reportSingleClassLayoutB 从这个内存布局就可以看出来 class A class A1 和 ClassB 的大小 本身 class A 的大小应该是1bytes的内存定位大小加上虚函数指针4bytes因为有了虚函数指针后1bytes 的占位就可以取消了 所以 A 的大小就是 4bytes 同理 Class A1 对于 Class B 它主要是 从 class A 和 class A1 虚继承 而来 所以 B 里面包含有一个 A 和 A1 同时因为是需继承 所以就有一个指向虚基类 A1 的 vbptr 指针 这里为了方便我做个图直观一点 所以说 class B 的大小是 12bytes 代码二 代码二 cpp view plaincopyprint 本文由西安白癜风医院 本文由西安白癜风医院 1 class A 2 3 int a 4 5 class B 6 7 int b 8 9 10 class C 11 12 13 class D 14 15 16 class E public virtual A public virtual B public virtual C public vir tual D 17 18 19 void main 20 21 cout sizeof E sizeof E 0 0 3 1 1 4 Ed E 0 A 本文由西安白癜风医院 本文由西安白癜风医院 4 1 2 8 Ed E 0 B 5 1 3 12 Ed E 0 C 6 1 4 16 Ed E 0 D 一般都是把 vbtable 放在对象的前面 所以 vbtable virtual base class table 与对象首地址的偏移量一般就是中间隔着 vbtable 这个地方的 4 表示 E 的 vbtable 与虚基 类 A 首地址的偏移量 同理 8 12 16 这个就不用我说了 既然这都给出了 vbtable 域虚 基类的地址偏移量了 说明在 E 对象的内存中还是存在分配的空间 从 vs2010 的内存来看的确也是分配了 通过前面的 vbtable 的偏移来看对象的大 小就是 16bytes a 是 class A 的首地址 b 是 classB 的首地址 有人会问为什么不是 20bytes 上面的内存分配偏移是 16 就说明有 20bytes 偏移 16 刚好在变量 b 的下面分 配 4bytes 的 C 这说的不准确 不过好明白 这样偏移是 16 的地方就是 D vbtable 现在 可以正常定位 Class D 为空 就没有必要再分配 4bytes 的空间 所以 sizeof E 的大小应 本文由西安白癜风医院 本文由西安白癜风医院 该是 vbtable 指针 4bytes 固定局部 a b 工 8bytes C 的 4bytes 这有点不好明 白 不过下面我还有例子 加深理解 代码三 代码三 cpp view plaincopyprint 1 class A 2 3 4 class B 5 6 int b 7 8 9 class C 10 11 12 class D 13 14 15 class E public virtual A public virtual B public virtual C public vir tual D 16 17 18 void main 19 20 cout sizeof A sizeof A endl 21 cout sizeof B sizeof B endl 22 cout sizeof C sizeof C endl 23 cout sizeof D sizeof D endl 24 cout sizeof E sizeof E endl 25 上面代码二输出的结果 这回感觉还是很奇怪吧 看看内存布局吧 本文由西安白癜风医院 本文由西安白癜风医院 首先 看看 vbtable 把 是不是很奇怪 为什么 A B 的偏移都是 4 ClassA 本身就 是空 刚好 ClassB 有一个成员所以肯定需要给 classB 分配内存的 所以这样就可以找到 A 的偏移 Class C 和 Class D 就没办法了没办法计算偏移 所以就给 ClassC 分配了内存 ClassC 有了内存这样 D 就可以的偏移也就出来了 这时候就有人问为什么 ClassD 的偏移 为什么不是 8 呢 说实话我也没搞懂 我的猜想是对象本身为空 但是为了内存对齐所以 就是 4bytes 希望懂的大神给以指点 我通过调试多个例子 得出来的 下面的例子就就 更好的说明了这点 代码四 代码四 cpp view plaincopyprint 1 class A 2 3 4 class B 5 6 7 8 class C 9 10 11 class D 12 13 本文由西安白癜风医院 本文由西安白癜风医院 14 class E public virtual A public virtual B public virtual C public vir tual D 15 16 17 void main 18 19 E ee 20 cout sizeof A sizeof A endl 21 cout sizeof B sizeof B endl 22 cout sizeof C sizeof C endl 23 cout sizeof D sizeof D e

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论