C++的类和new和delete和菱形继承机制
文章目录
- 参考
- 虚函数
- 使用虚函数的class结构
- 相关实现
- 源码
- IDA反编译
- 子类虚表和父类虚表
- 调用函数
- 菱形继承
参考
https://showlinkroom.me/2017/08/21/C-%E9%80%86%E5%90%91%E5%88%86%E6%9E%90/
https://www.cnblogs.com/bonelee/p/17299985.html
https://xz.aliyun.com/t/5242?time__1311=n4%2BxnD07itGQ%3DD54AKDsA3xCuU%3DwQNY4D&alichlgref=https%3A%2F%2Fxz.aliyun.com%2Fu%2F15779#toc-3
虚函数
在C++中,虚函数(virtual function)是一种特殊的成员函数,它允许在派生类中重写或覆盖基类中定义的函数,从而实现多态性(polymorphism)。虚函数的关键特征和用途可以概括如下:
-
声明与定义:
要声明一个虚函数,需要在基类的成员函数声明前加上virtual关键字。例如:class Base { public:virtual void someFunction() {// 基类的实现} };派生类可以重写该函数,也可以不重写,如果重写,则在派生类中提供新的实现:
class Derived : public Base { public:void someFunction() override {// 派生类的实现} }; -
虚函数表(VTable):
实现虚函数的机制通常涉及到虚函数表(Virtual Table,简称vtable)。每个含有虚函数的类都会有一个虚函数表,表中存储着该类所有虚函数的地址。每个对象都有一个指向相应类虚函数表的指针(称为vptr)。当通过基类指针或引用调用虚函数时,程序会根据对象的vptr查找到正确的虚函数表,从而调用实际对象类型的函数实现。 -
纯虚函数与抽象类:
如果基类中的虚函数没有提供实现,并且在声明时被= 0初始化,那么这个函数被称为纯虚函数。含有纯虚函数的类不能实例化,只能作为基类被继承,这样的类称为抽象类。
使用虚函数的class结构

相关实现

- new的本质,实际上就是malloc+构造函数
- delete的本质就是析构函数+free

源码
#include <iostream>
#include <string>using namespace std;class Person
{public:Person() {age = 0;name = "";};~Person() {};virtual void setName(string name) = 0;virtual void setAge(int age) = 0;
protected:int age;string name;};class Student :public Person {public:Student() {age = 17;}void setName(string name) {this->name = name;}string getName() {return this->name;}void setAge(int age) {if (age > 30 || age < 6) {cout << "not suitable for school!" << endl;return;}this->age = age;}int getAge() {return this->age;}
};int main() {Student* stu = new Student();stu->setName("Link");stu->setAge(18);cout << stu->getName() << " with age " << stu->getAge() << endl;return 0;
}
IDA反编译

子类构造函数

父类构造函数

子类虚表和父类虚表

纯虚函数的抽象类的虚表由__cxa_pure_virtual填充,有几个纯虚函数就有几个__cxa_pure_virtual,student类虚表分别有各自实现的虚函数,虚表上面是该类的typeinfo的地址

- RTTI (Run-Time Type Information) 是C++的一项特性,允许程序在运行时识别对象的类型。
typeid运算符和dynamic_cast都是基于RTTI实现的。- 每个包含虚函数的类实例,在内存中都有一个隐藏的指针(称为vptr,虚函数指针),指向该类的虚函数表(vtable)。这个vptr是在对象创建时由编译器自动初始化的。
- RTTI信息通常与vtable一起管理,其中可能包括类型描述信息和继承链信息等。
-
Aclass* ptra = new Bclass;:这行代码创建了一个指向Bclass实例的指针,但这个指针被声明为Aclass*类型。因为Bclass是Aclass的子类(假设如此),所以这是向上转型,是多态的基础。 -
int ** ptrvf = (int**)(ptra);:这里进行了一次不安全的类型转换,将Aclass指针转换为了int**。这种转换通常是为了直接访问虚函数指针(vptr),因为在许多系统上,vptr是对象内存布局的第一个元素,可以被视为一个指针的指针。但是,请注意,这种做法非常危险且非标准,违反了类型安全原则。 -
*((int*)ptrvf[0]-1):这一部分是为了找到RTTI信息的位置。ptrvf[0]访问的是第一个虚函数(按指针算起),减1则是尝试访问vptr前的一个位置,期望那里存放着RTTI相关数据的指针。这一步同样非常危险,依赖于特定编译器和平台的实现细节。 -
*((RTTICompleteObjectLocator*)(...)):这里进一步将找到的地址强制转换为RTTICompleteObjectLocator指针,并解引用它。RTTICompleteObjectLocator是一个内部使用的结构(非标准公开接口),用于存储有关对象类型的完整信息,比如类的类型描述符、偏移量到类型名称字符串等。
调用函数

对于虚函数
- 先通过对象开始八个字节得到虚表地址
- 通过虚表地址和相关偏移得到函数地址
- 调用函数
对于非虚函数 - 直接调用再text段实现的函数
菱形继承
#include<stdio.h>
#include<stdlib.h>//间接基类
class A {
public:virtual void function() {printf("A virtual function\n");}int a;
};//直接基类
class B :virtual public A { //虚继承
public:virtual void func() {printf("B virtual func()\n");}int b;
};//直接基类
class C :virtual public A { //虚继承
public:virtual void func() {printf("C virtual func()");}int c;
};//派生类
class D :public B, public C {
public:virtual void function() {printf("D virtual function()");}int d;
};int main(int argc, char** argv) {A* A_ptr = (A*)new D();A_ptr->function();return 0;
}
B和C继承A,D继承B和C
通过虚表地址减去24后的位置的内容是32,然后再加上起始地址,对应到的V4为D内的A的对象内存位置,offset vbase应该是与虚基类的偏移也就是和A的偏移


这里给各个父类对象在本对象的空间的前八个字节赋值时,用的是本对象虚表对应到的不同父类的虚函数的地址

此时对应的虚表地址,所以**两次得到D::function的地址,然后参数为对象自己

相关文章:
C++的类和new和delete和菱形继承机制
文章目录 参考虚函数使用虚函数的class结构相关实现源码IDA反编译子类虚表和父类虚表调用函数菱形继承 参考 https://showlinkroom.me/2017/08/21/C-%E9%80%86%E5%90%91%E5%88%86%E6%9E%90/ https://www.cnblogs.com/bonelee/p/17299985.html https://xz.aliyun.com/t/5242?t…...
Redis教程(二十二):Redis的过期删除和缓存淘汰策略
传送门:Redis教程汇总篇,让你从入门到精通 一、过期删除策略 Redis 中的过期删除策略是与 Redis 管理键的生命周期相关的一系列操作,用于删除过期的Key以释放内存。Redis 提供了三种主要的过期删除策略: 1、惰性删除(Lazy Expiration) 工作原理:当客户端尝试访问一个…...
Lodop 实现局域网打印
文章目录 前言一、Lodop支持打印的方式lodop 打印方式一般有3种:本地打印局域网集中打印广域网AO打印 二、集成步骤查看lodop 插件的服务端口:查看ip后端提供接口返回ip,前端动态获取最后步骤 前言 有时候会根据不同的ip来获取资源文件&…...
HarmonyOS(二十四)——Harmonyos通用事件之触摸事件
1.触摸事件。 触摸事件是HarmonyOS通用事件的一种事件之一,当手指在组件上按下、滑动、抬起时触发。 名称是否冒泡功能描述onTouch(event: (event?: TouchEvent) > void)是手指触摸动作触发该回调,event返回值见下面TouchEvent介绍。 2. TouchEve…...
2024-前端面试的正确打开方式(GitHub火爆场景题剖析)
写在前面 最近前端面试大家有没有感觉到场景题的压迫感!!! 很显然普通面试八股不会怎么更新,而且就前端来说,面试并不是真正困难的,常规八股显示不出面试者的技术水平。 前端作为一个技术行业,…...
Vue3项目炫酷实战,检测密码强度值
在前端项目开发中,确保用户密码的强度是保护账户安全的重要措施。本文将演示如何使用Vue 3实现一个简单的密码强度检测功能。通过实时反馈,帮助用户创建更安全的密码,从而提升整体系统的安全性。无论您是前端开发新手还是经验丰富的开发者&am…...
PHP实现抖音小程序用户登录获取openid
目录 第一步、抖音小程序前端使用tt.login获取code 第二步、前端拿到code传给后端 第三步、方法1 后端获取用户信息 第四步、方法2 抖音小程序拿到用户信息把用户信息传给后端 code2Session抖音小程序用户登录后端文档 第一步、抖音小程序前端使用tt.login获取code 前端 …...
Linux进程无法被kill
说明:记录一次应用进程无法被kill的错误; 场景 在一次导出MySQL数据时,使用下面的命令,将数据库数据导出为.sql文件,数据量大,导出时间长,于是我就将服务器重启了。 mysqldump -u username -…...
MySQL binlog三种模式
1.statement statement 记录的是sql语句。比如一条sql,update table_user set age 20 where id between 1 and 100。这条sql会更新100条数据,但是statement 模式下只会记录这条sql语句。 优点:不需要记录数据的变化,减少了bin …...
【CentOS 7】挑战探索:在CentOS 7上实现Python 3.9的完美部署指南
【CentOS 7】挑战探索:在CentOS 7上实现Python 3.9的完美部署指南 大家好 我是寸铁👊 总结了一篇【CentOS 7】挑战探索:在CentOS 7上实现Python 3.9的完美部署指南详细步骤✨ 喜欢的小伙伴可以点点关注 💝 前言 此篇教程只适用于p…...
oracle删除表空间和用户命令
创建表空间和用户可参考 ORACLE创建表空间,用户,修改密码,分配权限,以及导入导出_oracle表空间的密码-CSDN博客 1.删除表空间 --删除空的表空间,但是不包含物理文件 drop tablespace tablespace_name; --删除非空表空间,但是不包含物理文件 drop tabl…...
企业微信hook接口协议,ipad协议http,获取未发送群发列表
获取未发送群发列表 参数名必选类型说明uuid是String每个实例的唯一标识,根据uuid操作具体企业微信 请求示例 {"uuid":"1753cdff-0501-42fe-bb5a-2a4b9629f7fb" } 返回示例 {"data": {"listdata": [{"now_cnt&qu…...
oracle中的INTERVAL函数学习总结
Oracle 从9i数据库开始引入了一种新特性,可以用来存储时间间隔,出现了INTERVAL 函数。这个函数的表达式比较多,初学比较费劲不好掌握,经过以几个小时的查阅资料和实验,总结如下: interval year t…...
爬虫(没)入门:用 node-crawler 爬取 blog
起因 前几天想给一个项目加 eslint,记得自己曾经在博客里写过相关内容,所以来搜索。但是发现 csdn 的只能按标题,没办法搜正文,所以我没搜到自己想要的内容。 没办法只能自己又重新折腾了一通 eslint,很烦躁。迁怒于…...
GAMES104笔记
GAMES104 文章目录 GAMES10401.从入门到实践什么是游戏引擎学习顺序 02.引擎架构分层资源层功能层核心层平台层工具层总结 03.如何构建游戏世界其它需要管理的复杂情况 04.游戏引擎中的渲染实践Rendering游戏引擎中的绘制知识点(结合实际进化而来)渲染基…...
ARM功耗管理架构演进及变迁
安全之安全(security)博客目录导读 目录 一、功耗管理架构演进及变迁概述 二、多核 三、big.LITTLE 四、DynamIQ...
ARM-V9 RME(Realm Management Extension)系统架构之系统能力的设备隔离和保护
安全之安全(security)博客目录导读 目录 三、设备隔离和保护 1、外设隔离 2、非pe请求者(设备)...
如何为律师制作专业的商务名片?含电子名片二维码
律师关注细节,律师名片也不例外。它们不仅仅是身份的象征,更是律师专业形象的代表,传递专业知识和信任。今天就来和我们一起来看看制作律师商务名片的注意事项,以及如何制作商务名片上的电子名片二维码? 一、名片的主…...
方案设计|汽车轮胎数显胎压计方案
一、引言 数显轮胎胎压计是一个专门测量车辆轮胎气压的工具,它具有高精度测量的功能,能够帮助快速准确获取轮胎气压正确数值,保证轮胎使用安全。本文将对数显轮胎胎压计的方案技术进行分析,包括其基本原理、硬件构成、软件设计等方…...
MySQL学习——选项文件的使用
MySQL 的许多程序都可以从选项文件(有时也被称为配置文件)中读取启动选项。选项文件提供了一种方便的方式来指定常用的选项,这样你就不必每次运行程序时都在命令行上输入这些选项。 要确定一个程序是否读取选项文件,你可以使用 -…...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...
Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?
Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...
技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...
