由于一直对C++的多态心存疑虑,今天想彻底弄明明一点,所以做了一些测试,将结果拿出来同大家一起分享。测试在VC6下进行,以下是测试时用的继承关系以及虚函数的重写情况(不能贴图,可惜,可能贴源码了):

class BaseA

{

public:

BaseA();

~BaseA();

virtual void printme();

virtual void printme1();

};

class BaseB : public BaseA

{

public:

BaseB();

~BaseB();

virtual void printme();

};

class BaseC :public BaseA

{

public:

BaseC();

~BaseC();

virtual void printme();

};

class BaseD:public BaseB,BaseC

{

public:

BaseD();

~BaseD();

virtual void printme();

virtual void dxx();

};

class BaseF : public BaseD

{

public:

BaseF();

~BaseF();

virtual void printme1();

};

1、如果继承体系里没有C类,即粗线的单重继承,则以下测试代码是可行的(先从类实例地址的开始处取得指向vtable的指针,vtable是一个指针数组,每一个值都指向一个虚函数,因此可以顺序递增去执行每一个方法):

void *getp (void* p)

{

return (void*)*(unsigned long*)p;

}

fun getfun (BaseD* obj, unsigned long off)

{

void *vptr = getp(obj);

unsigned char *p = (unsigned char *)vptr;

p += sizeof(void*) * off;

return (fun)getp(p);

}

void testv()

{

BaseF *p = new BaseF;

fun f = getfun(p, 0);

(*f)();

f = getfun(p, 1);

(*f)();

}

输出为:

is BaseD here

is BaseF here 1

虚函数表图如下:

---------图没贴上来-------------------

b1

BaseD

BaseB

BaseA

_vfptr

[0]             BaseD::printme(void)

[1]             BaseF::printme1(void)

其中:BaseF *b1 = new BaseF;

此时,如果你想直接调用A的printme1方法,可用如下方法:

b1->BaseA::printme();

2、如果在继承层次中加入C类,则有了多重继承,以下将是b1的虚函数图:

---------图没贴上来-------------------

b1                                        0x02193a10

BaseD

BaseB

BaseA

_vfptr                 0x004380fc const BaseF::’vftable’{for’baseB’}

[0]                0x00401154 BaseD::printme(void)

[1]                0x004010af BaseF::printme1(void)

BaseC

BaseA

_vfptr                 0x004380f0 const BaseF::’vftable’{for’baseC’}

[0]                0x00401172 [thunk]:BaseD::printme’adjustor{4}’(void)

[1]                0x0040116D[thunk]:BaseF::printme1’adjustor{4}’(void)

(此时用上面的代码手动调用虚函数将会出错,具体内存是如何分布的,我没有去深入研究了)

可以看到,每一个继承分支都有不同的虚函数表,此时,如果你想用:

b1->BaseA::printme();

来调用A的方法,编译将通不过,告诉你会有歧义。而必须用:

((BaseC *)b1)->BaseA::printme();

来调用。

有关C++多态的一些测试相关推荐

  1. 【Kotlin】Kotlin 面向对象 ( 类 | 成员变量 | 成员方法 | 封装 | 继承 | 多态 )

    文章目录 I . 创建简单类 ( 整型字段 ) II . 创建简单类 ( 整型字段 + 字符串字段 ) III . 类方法定义 IV . 封装 V . 继承 VI . 多态 与 抽象类 I . 创建简 ...

  2. java的知识点13——多态、对象的转型(casting)、final关键字、抽象方法和抽象类、接口的作用、如何定义和使用接口?、接口的多继承、面向接口编程

    多态 多态指的是同一个方法调用,由于对象不同可能会有不同的行为.现实生活中,同一个方法,具体实现会完全不同. 多态的要点: 1. 多态是方法的多态,不是属性的多态(多态与属性无关). 2. 多态的存在 ...

  3. 重构—改善既有代码的设计4——构筑测试体系

    编写优良的测试程序,可以极大提高编程速度,即使不进行重构也一样. 自测试代码的价值: 程序员花时间最多的是用来调试:修复错误通常是比较快的,找出错误却是恶梦一场:当修好一个错误,总会有另一个错误出现, ...

  4. 1-11 Java 多态、类型转型

    文章目录 1.业务场景 2.多态调用 3.多态应用 1)业务场景 2)传统代码实现 3)问题思考 4)多态代码实现 4.向上.向下转型 1)举例 2)小总结 面向对象特征:抽象.封装.继承和多态,这些 ...

  5. java学习笔记day09 final、多态、抽象类、接口

    java学习笔记day09 思维导图 final . 多态 . 抽象类 . 接口 (都很重要) 一.final 二.多态 多态中的成员访问特点⭐ [P237] 多态的好处 [P239] 多态的弊端 向 ...

  6. java:多态详解,以及对象的向上和向下转型

    大家好,兔胆包天我又来啦,今天给大家分享的是多态,多态最主要的是父类引用指向子类对象,还是老办法,直接上代码,代码中注解的很详细哦. 这是第一个代码: //测试多态 public class Anim ...

  7. Educoder- 《JAVA从小白到大牛》(第二章)2-3 Java面向对象 - 封装、继承和多态的综合练习

    提示:本文章为个人学习记录,仅供参考学习,禁止转载,支持交流与讨论. 文章目录 第1关:通关任务一 任务描述 相关知识 面向对象思想 封装 继承 `super()`和`this()` 编程要求 测试说 ...

  8. Java面向对象 - 封装、继承和多态的综合练习

    面向对象的三个基本特征: 封装,就是把客观的事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的信息隐藏.隐藏实现细节,使得代码模块化. 继承,可以使用现有类的所有功能 ...

  9. 【Java SE】面向对象三大特性之多态

    何为多态? 多态,通俗一点说就是在完成某一个行为的时候,不同的对象会产生不同的形态. 比如说:打印机在完成打印行为的时候,可以根据不同的对象打印不同的类型,有黑白,有彩色等等,打印的结果是不一样的. ...

最新文章

  1. Zend Framework中,执行自定义sql语句
  2. spring原理案例-基本项目搭建 01 spring framework 下载 官网下载spring jar包
  3. 数学建模之图像处理---颜色建模
  4. 批改网作文提交时分析不出来_小学生作文写作从哪些方面提高呢?
  5. 解决HttpServletResponse输出中文乱码问题
  6. MongoDB-pymongo
  7. 实验12 编写0号中断的处理程序
  8. 诺基亚手机新品发布定档 6 月 11 日!Nokia C20 Plus 即将到来
  9. 海康相机回调方式理一下
  10. jackson的简单实用实例(json)
  11. python以追加方式打开文件 线程安全吗_Python多线程同步---文件读写控制方法
  12. Java 打印对象的地址
  13. ant构建异常UNEXPECTED TOP-LEVEL EXCEPTION com.android.dx.cf.iface.ParseException解决
  14. DNS的更新和ddns(动态域名解析)
  15. 17-chan原理1-创建
  16. 获取高薪职位的六个妙计
  17. matlab坐标旋转平移缩放,MATLAB实现RGB图像的平移、缩放和旋转
  18. 高低温磁场型霍尔效应测试仪的设计方案
  19. 第一个Ajax程序给我的下马威——xmlHttp的status=0?
  20. lammps模拟中tersoff势设置方法

热门文章

  1. 2021年信息系统项目管理师案例分析第二题讲解
  2. 软考准考证打印详细步骤(打印一张纸上)
  3. 信息系统项目管理师:第9章:项目人力资源管理-历年真题
  4. java基础知识1---面向对象及final,finally,finalize区别
  5. 《系统集成项目管理工程师》必背100个知识点-74CMO的具体工作
  6. MyBatis中动态sql实现时间范围比较的查询
  7. Vue实现仿音乐播放器11-实现访问百度音乐API实现播放音乐功能
  8. springboot-自动配置原理
  9. 在“软件工程:研究与实践”研讨会上关于UML Use-Case的开放空间讨论
  10. Dart微基准测试第一部分