c++——多态(补充)

news2025/1/11 2:42:32

优先查看:c++——多态_Hiland.的博客-CSDN博客


目录

菱形虚拟继承子类的重写问题

菱形虚拟继承中的偏移量补充

逆向思维——汇编查看多态中被重写的虚函数


菱形虚拟继承子类的重写问题

继承环节时,菱形虚拟继承解决了菱形继承的数据冗余和二义性问题。菱形虚拟继承在多态中使用会出现一些问题,有如下代码:

class A
{
public:
	virtual void func() {}
	int _a;
};
//继承A
class B : virtual public A
{
public:
	virtual void func() {}
    virtual void func1() {}
	int _b;
};
//继承A
class C : virtual public A
{
public:
	virtual void func() {}
	int _c;
};
//继承B和继承C
//当B和C都采用虚继承继承A,并且重写了A中的func虚函数,D继承了B和C,D必须重写A中的func虚函数
//否则D无法知道将B的虚函数写入虚表中还是将C的虚函数写入虚表中
class D : public B,  public C
{
public:
	//必须重写func
	//virtual void func() {}
	int _d;
};

int main()
{
	D d;
	d.B::_a = 1;
	d.C::_a = 2;
	d._b = 3;
	d._c = 4;
	d._d = 5;
	return 0;
}

运行如上代码,编译器报错,报错如下:

当B和C都采用虚继承继承A,并且重写了A中的func虚函数,D继承了B和C,D必须重写A中的func虚函数,否则D无法知道将B的虚函数写入虚表中还是将C的虚函数写入虚表中,因此D必须重写func函数。

菱形虚拟继承中的偏移量补充

(1条消息) c++——继承_Hiland.的博客-CSDN博客

将上述代码修改后运行并查看内存窗口里的偏移量时,之前发现偏移量上方还有一个00000000的数据,在多态时使用到了该数据。如下图:

此时由于B类增加了一个虚函数,所以B中有一个对应的虚表,根据内存窗口查看得知第二个就是之前在继承阶段每个类距离a的偏移量,查询b中的偏移量地址,发现如下图:

本该在继承阶段的那个00000000 变成了fcffffff,这个其实是该类到虚表的偏移量,所以该值是在多态中使用到的。

逆向思维——汇编查看多态中被重写的虚函数

当我们在vs下针对多继承问题想查看子类后面的虚函数时会使用以下代码:

class Base1 {
public:
    virtual void func1() { cout << "Base1::func1" << endl; }
    virtual void func2() { cout << "Base1::func2" << endl; }
private:
    int b1;
};
class Base2 {
public:
    virtual void func1() { cout << "Base2::func1" << endl; }
    virtual void func2() { cout << "Base2::func2" << endl; }
private:
    int b2;
};
class Derive : public Base1, public Base2 {
public:
    virtual void func1() { cout << "Derive::func1" << endl; }
    virtual void func3() { cout << "Derive::func3" << endl; }
private:
    int d1;
};
typedef void(*VFPTR) ();
void PrintVTable(VFPTR vTable[])
{
    cout << " 虚表地址>" << vTable << endl;
    for (int i = 0; vTable[i] != nullptr; ++i)
    {
        printf(" 第%d个虚函数地址 :0X%x,->", i, vTable[i]);
        VFPTR f = vTable[i];
        f();
    }
    cout << endl;
}
int main()
{
    Derive d;
    VFPTR* vTableb1 = (VFPTR*)(*(int*)&d);//Base1类
    PrintVTable(vTableb1);
    VFPTR* vTableb2 = (VFPTR*)(*(int*)((char*)&d + sizeof(Base1)));//Base2类
    PrintVTable(vTableb2);
    return 0;
}

我们已经查看了派生类的虚函数也进了虚表中,但是在vs的监视窗口中我们发现了基类和派生类的func1函数地址不同,在debug下查看监视窗口,出现如下图的情况:

同样是在d的派生类对象中,Base1部分的func1函数和Base2部分的func1函数地址不同,Base1部分func2函数和Base2部分的func2函数不同,在这里以func1函数为例探索,先在main函数中打印d对象中的func1函数地址看看:

对比打印虚表中的Base1部分的func1函数,虚表中的Base2部分的func1函数,以及直接打印d对象中func1函数,发现Base1和Base2中的函数地址不一样且和d对象中的func1函数地址都不一样

为了查看究竟是发生了什么,我们在vs下进行反汇编,通过汇编过程查看Base1和Base2中分别在调用func1的过程

通过反汇编查看的Base1中的func1函数的调用:

 

通过反汇编查看的Base2中的func1函数的调用:

通过以上的Base1和Base2两个类分别调用func1,能够得到以下的结论:

这里运用的就是逆向思维,通过汇编代码来查看一些编译器中出现的无法理解的现象。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/760466.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C# Modbus通信从入门到精通(11)——Modbus RTU(调试软件Modbus Slave和Modbus Poll的使用)

前言 我们在开发Modbus程序的时候,会需要测试以下我们写的Modbus程序有没有问题,这时候就需要使用到Modbus Slave和Modbus Poll这两个软件,Modbus Slave是模拟Modbus从站,Modbus Poll是模拟Modbus从站主站的, 1、Modbus Slave 一般情况下我们开发的嗾使Modbus主站程序,…

性能测试(Jemeter)

1.性能指标 响应时间&#xff1a;一次请求的往返时间tps&#xff1a;每秒系统能够处理的事务数&#xff0c;比如订单中的下单操作&#xff0c;下单后续有很多操作&#xff0c;比如创建订单&#xff0c;扣除库存&#xff0c;清算库存等&#xff0c;这个完整操作就是一个完整的事…

【数据分享】1929-2022年全球站点的逐日最大持续风速数据(Shp\Excel\12000个站点)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、能见度等指标&#xff0c;说到气象数据&#xff0c;最详细的气象数据是具体到气象监测站点的数据&#xff01; 对于具体到监测站点的气象数据&#xff0c;之前我们分享过1929-2022年全球气象…

Qt添加第三方字体

最近开发项目时&#xff0c;据说不能用系统自带的微软雅黑字体&#xff0c;于是找一个开源的字体&#xff0c;思源黑体&#xff0c;这个是google和Adobe公司合力开发的可以免费使用。本篇记录一下Qt使用第三方字体的方式。字体从下载之家下载http://www.downza.cn/soft/266042.…

Pytest参数化——那些你不知道的使用技巧

目录 前言 装饰测试类 输出 说明 装饰测试函数 单个数据 输出 说明 一组数据 输出 说明 图解对应关系 组合数据 输出 说明 标记用例 输出 说明 嵌套字典 输出 增加可读性 使用ids参数 输出 说明 自定义id做标识 输出 说明 总结 总结&#xff1a; 前…

给你二叉树的根节点 root ,返回它节点值的中序遍历

题目&#xff1a;给你二叉树的根节点 root &#xff0c;返回它节点值的中序遍历。 要求&#xff1a;非递归实现。 1/ \2 3/ \ / \4 5 6 7中序遍历结果为&#xff1a; 4 2 5 1 6 3 7这里考察中序遍历思想&#xff0c;使用Stack的后进先出特性输出结果。 TreeNode树状结…

spring项目的创建和使用(详细教程 手把手)方法一

今天我们来讲使用maven方式创建一个sping项目。 1、创建一个普通的maven项目。 2、添加spring框架(引入依赖)支持。添加到pom.xml文件中。 添加的框架有 spring-context&#xff1a;spring 上下⽂&#xff0c;还有 spring-beans&#xff1a;管理对象的模块。 <dependenc…

python将.h5文件转换成csv

五、在jupyter中找到results文件夹&#xff0c;然后可以把跑的.h5结果转换为csv文件 pip install tables import h5py import numpy as np import pandas as pd filename Mnist_FEDL_0.003_0_10u_20b_5_avg.h5 f h5py.File(filename, r) # List all groups print("K…

SpringMVC【文件上传(原生方式上传、上传多文件、异步上传、跨服务器上传 ) 】(五)-全面详解(学习总结---从入门到深化)

目录 SpringMVC文件上传_原生方式上传 SpringMVC文件上传_SpringMVC方式上传 SpringMVC文件上传_上传多文件 SpringMVC文件上传_异步上传 SpringMVC文件上传_跨服务器上传 SpringMVC文件上传_原生方式上传 上传是Web工程中很常见的功能&#xff0c;SpringMVC框架简化了文…

17、SQL注入之二次、加解密、DNS等注入

目录 加解密二次注入DNSlog注入涉及资源:中转注入 加解密 %3D是等号 值在带入数据库之前是有一个解码的操作&#xff0c;明文在解码的时候&#xff0c;就会出现问题&#xff0c;进而影响到语句&#xff1b;密文和明文在一起&#xff0c;这种网站后台是识别不了的&#xff1b;只…

P1332 血色先锋队

血色先锋队 题目背景 巫妖王的天灾军团终于卷土重来&#xff0c;血色十字军组织了一支先锋军前往诺森德大陆对抗天灾军团&#xff0c;以及一切沾有亡灵气息的生物。孤立于联盟和部落的血色先锋军很快就遭到了天灾军团的重重包围&#xff0c;现在他们将主力只好聚集了起来&…

银行家算法C语言代码

/*the code simulate blank algorithm to void deadlock*/ /*author:RongGong*/#include<stdio.h> #define MAX_RES_PROC 100//定义银行家算法的数据结构 int M; // 资源的个数 int N; // 进程的个数 int Available[MAX_RES_PROC] {0}; //可利用资源向量 int MaxNeed[MA…

我们如何在 Elasticsearch 8.6、8.7 和 8.8 中加速数据摄入

作者&#xff1a;Adrien Grand, Joe Gallo, Tyler Perkins 正如你们中的一些人已经注意到的&#xff0c;Elasticsearch 8.6、8.7 和 8.8 在各种数据集上带来了良好的索引加速&#xff0c;从简单的关键字到繁重的 KNN 向量&#xff0c;以及摄取管道繁重的摄取工作负载。 摄取涉及…

Grafana_数据可视化工具

目录 一、简介 二、安装部署 1、下载 2、安装 3、启用 三、使用简介 1、添加数据源 2、创建DashBoard 3、查看dashboard 4、选择查看的时间段 5、阈值颜色控制 源码等资料获取方法 一、简介 Grafana是一个跨平台开源的纯html/js编写的度量分析和可视化工具&#x…

Hydra(九头蛇)密码破解工具的详细使用教程

简介 Hydra是⼀款开源的暴⼒密码pojie⼯具&#xff0c;⽀持多种协议密码的破译。 可以对多种服务的账号和密码进行爆破&#xff0c;包括 数据库、SSH、FTP 等服务&#xff0c;在 Kali Linux 中自带 Hydra。有了这个工具就可以很方便的对密码进行破解。 其简单的使用参数如下&a…

【Java从入门到大牛】面向对象进阶上篇

&#x1f525; 本文由 程序喵正在路上 原创&#xff0c;CSDN首发&#xff01; &#x1f496; 系列专栏&#xff1a;Java从入门到大牛 &#x1f320; 首发时间&#xff1a;2023年7月16日 &#x1f98b; 欢迎关注&#x1f5b1;点赞&#x1f44d;收藏&#x1f31f;留言&#x1f43…

Python应用实例(二)数据可视化(二)

数据可视化&#xff08;二&#xff09; 1.随机漫步1.1 创建RandomWalk类1.2 选择方向1.3 绘制随机漫步图1.4 模拟多次随机漫步1.5 设置随机漫步图的样式 1.随机漫步 使用Python来生成随机漫步数据&#xff0c;再使用Matplotlib以引人瞩目的方式将这些数据呈现出来。随机漫步是…

服务器感染了.halo勒索病毒,如何确保数据文件完整恢复?

引言&#xff1a; 随着信息技术的飞速发展&#xff0c;网络安全威胁也日益猖獗&#xff0c;勒索病毒作为其中的一种&#xff0c;给个人和企业带来了巨大的威胁。.halo勒索病毒作为最近出现的一种恶意软件&#xff0c;以其高度复杂的加密算法和迅速的传播方式而备受关注。它通过…

【群智能算法改进】一种改进的猎人猎物优化算法 IHPO算法[1]【Matlab代码#49】

文章目录 【获取资源请见文章第5节&#xff1a;资源获取】1. 原始HPO算法2. 改进后的IHPO算法2.1 Cubic映射初始化2.2 透镜成像折射反向学习2.3 强制切换策略 3. 部分代码展示4. 仿真结果展示5. 资源获取 【获取资源请见文章第5节&#xff1a;资源获取】 1. 原始HPO算法 此算法…

Vue3工程化项目搭建

Vue3工程化项目搭建 源码&#xff1a;vue3-quick-start 预览&#xff1a;vue3-quick-start 一、何为工程化 工程化概述 前端工程化大致可以分为模块化、组件化、规范化和自动化。 规范化 项目目录结构语法提示编码风格规范联调规范文件命名规范代码样式规范git flow 模块…