C++对象模型中加入多继承


从单继承可以知道,派生类中只是扩充了基类的虚函数表。如果是多继承的话,又是如何扩充的?

1)        每个基类都有自己的虚表。

2)        子类的成员函数被放到了第一个基类的表中。

3)        内存布局中,其父类布局依次按声明顺序排列。

4)        每个基类的虚表中的print()函数都被overwrite成了子类的print ()。这样做就是为了解决不同的基类类型的指针指向同一个子类实例,而能够调用到实际的函数。

上面3个类,Derived_Mutlip_Inherit继承自Base、Base_1两个类,Derived_Mutlip_Inherit的结构如下所示:

为了验证上述C++对象模型,我们编写如下测试代码。

void test_multip_inherit()
{
Derived_Mutlip_Inherit dmi(3333);
cout << "对象dmi的起始内存地址:\t\t" << &dmi << endl;
cout << "虚函数表_vptr_Base地址:\t" << (int*)(&dmi) << endl;
cout << "_vptr_Base — 第1个函数地址:\t" << (int*)*(int*)(&dmi) << "\t即析构函数地址" << endl;
cout << "_vptr_Base — 第2个函数地址:\t" << ((int*)*(int*)(&dmi) + 1) << "\t";
typedef void(*Fun)(void);
Fun pFun = (Fun)*(((int*)*(int*)(&dmi)) + 1);
pFun();
cout << endl;
cout << "_vptr_Base — 第3个函数地址:\t" << ((int*)*(int*)(&dmi) + 2) << "\t";
pFun = (Fun)*(((int*)*(int*)(&dmi)) + 2);
pFun();
cout << endl;
cout << "_vptr_Base — 第4个函数地址:\t" << *((int*)*(int*)(&dmi) + 3) << "【结束】\t";
cout << endl;
cout << "推测数据成员iBase地址:\t\t" << ((int*)(&dmi) +1) << "\t通过地址取得的值:" << *((int*)(&dmi) +1) << endl; SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);
cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl;
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);
cout << "虚函数表_vptr_Base1地址:\t" << ((int*)(&dmi) +2) << endl;
cout << "_vptr_Base1 — 第1个函数地址:\t" << (int*)*((int*)(&dmi) +2) << "\t即析构函数地址" << endl;
cout << "_vptr_Base1 — 第2个函数地址:\t" << ((int*)*((int*)(&dmi) +2) + 1) << "\t";
typedef void(*Fun)(void);
pFun = (Fun)*((int*)*((int*)(&dmi) +2) + 1);
pFun();
cout << endl;
cout << "_vptr_Base1 — 第3个函数地址:\t" << *((int*)*(int*)((int*)(&dmi) +2) + 2) << "【结束】\t";
cout << endl;
cout << "推测数据成员iBase1地址:\t" << ((int*)(&dmi) +3) << "\t通过地址取得的值:" << *((int*)(&dmi) +3) << endl;
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);
cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl;
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);
cout << "推测数据成员iDerived地址:\t" << ((int*)(&dmi) +4) << "\t通过地址取得的值:" << *((int*)(&dmi) +4) << endl;
}

  输出结果如下图所示:

C++对象模型5--多继承下的对象模型的更多相关文章

  1. C++学习之路(九):从菱形继承引入的对象模型

    一.单继承 class A {int a;}; class B : public A {int b;}; 普通的单继承关系,类的大小是由其虚表指针和非静态成员函数大小决定.故上述sizeof(A)的大 ...

  2. C++对象模型:单继承,多继承,虚继承,菱形虚继承,及其内存布局图

    C++目前使用的对象模型: 此模型下,nonstatic数据成员被置于每一个类的对象中,而static数据成员则被置于类对象之外,static和nonstatic函数也都放在类对象之外(通过函数指针指 ...

  3. C++ //继承中的对象模型 //利用开发人员命令提示工具查看对象模型 //父类中所有非静态成员属性都会被 子类继承下去 //父类中私有成员属性 是被编译器给隐藏了 因此是访问不到 但是确实被继承下去了

    1 //继承方式 2 //语法:class 子类 :继承方式 父类 3 //继承方式 三种: 4 //1.公共继承 5 //2.保护继承 6 //3.私有继承 7 8 /* 9 #include &l ...

  4. sqlalchemy mark-deleted 和 python 多继承下的方法解析顺序 MRO

    sqlalchemy mark-deleted 和 python 多继承下的方法解析顺序 MRO 今天在弄一个 sqlalchemy 的数据库基类的时候,遇到了跟多继承相关的一个小问题,因此顺便看了一 ...

  5. JS中的继承(下)

    JS中的继承(下) 在上一篇 JS中的继承(上) 我们介绍了3种比较常用的js继承方法,如果你没看过,那么建议你先看一下,因为接下来要写的内容, 是建立在此基础上的.另外本文作为我个人的读书笔记,才疏 ...

  6. C++ 链式继承下的虚函数列表

    目录 1.虚函数列表的位置 2.虚函数列表的内容 3.链式继承中虚函数列表的内容   注: 虚函数列表 又称为虚表, vtbl , 指向它的指针称为vptr, vs2019中称为__vfptr 操作系 ...

  7. C++对象模型——&quot;无继承&quot;情况下的对象构造(第五章)

    5.1 "无继承"情况下的对象构造 考虑以下这个程序片段: 1 Point global; 2 3 Point foobar() 4 { 5 Point local; 6 Poin ...

  8. C++对象模型:单继承,多继承,虚继承

    什么是对象模型 有两个概念可以解释C++对象模型: 语言中直接支持面向对象程序设计的部分.对于各种支持的底层实现机制. 类中成员分类 数据成员分为静态和非静态,成员函数有静态非静态以及虚函数 clas ...

  9. C++对象模型的那些事儿之一:对象模型(上)

    前言 很早以前就听人推荐了<深入理解C++对象模型>这本书,从年初买来到现在也只是偶尔翻了翻,总觉得晦涩难懂,放在实验室上吃灰吃了好久.近期由于找工作对C++的知识做了一个全面系统的学习, ...

随机推荐

  1. Java程序员快速入门Go语言

    这篇文章帮助Java程序员快速入门Go语言. 转载至 开源中国社区. http://www.oschina.net 本文将以一个有代表性的例子为开始,以此让Java程序员对Go语言有个初步认识,随后将 ...

  2. 2016 Multi-University Training Contest 5&6 总结

    第五场和第六场多校都打得很糟糕. 能做到不以物喜不以己悲是假的,这对队伍的情绪也可以算上是比较大的打击. 很多时候我们发现了问题,但是依旧没有采取有效的方法去解决它,甚至也没有尝试去改变.这是一件相当 ...

  3. centos扩容(pv,vg,lv)

    preFace: (应用场景需求分析)

  4. Sprite Kit编程指南中文版下载

    下载地址:http://download.csdn.net/detail/xin814/6032573 关于Sprite Kit 重要提示:  这是API或开发技术的一个初版文档.虽然本文档的技术准确 ...

  5. MapReduce实现矩阵相乘

    矩阵相乘能够查看百度百科的解释http://baike.baidu.com/view/2455255.htm?fr=aladdin 有a和b两个矩阵 a:                1   2   ...

  6. Maven真——聚合和继承(于)

    依赖管理 我们谈论继承一个dependencies因素,我们非常easy这个特性被认为是适用于accout-parent于. 子模块account-email和account-persist同一时候依 ...

  7. JS学习笔记(三)函数

    js中的方法名一般都是首字母小写,其余单词首字母大写的规范. 声明 function 函数名(参数列表) { // 函数体 return 返回值; } 调用 函数名(); (js中花括号喜欢用这种方式 ...

  8. HTML之学习笔记(五)图片加载

    Html图片的处理一般采用<img>标签 语法:                例如<img src="地址" />            地址:      ...

  9. Android知识简单测试题

    上周去了一场Android考试,前面基础的题目很简单却答不上来,看过跟做过,懂了和会讲差距还是很大的,下面整理一下还记得的几个问题,自勉! 还是觉得,要好好看官方文档才是正道的啊! 1. Androi ...

  10. .net string format

    转自:http://www.cnblogs.com/jobs2/p/3948049.html 转自:http://jingyan.baidu.com/article/48206aeaf8c52f216 ...