当前位置: 首页 > news >正文

C++ 内存布局 - Part5: 继承关系中 构造析构与vptr的调整

这里以单继承为例,汇编采用AT&T格式,先看示例代码:

#include <iostream>class Base {
public:Base() {std::cout << "Base Constructor, this ptr: " << this << std::endl;printVptr();}virtual ~Base() {std::cout << "Base Destructor, this ptr: " << this << std::endl;printVptr();}virtual void printVptr() { std::cout << "Base::printVptr, vptr = " << *(void **)this << std::endl; }int a;int b;
};class Derived : public Base {
public:Derived() {std::cout << "Derived Constructor, this ptr: " << this << std::endl;printVptr();}~Derived() {std::cout << "Derived Destructor, this ptr: " << this << std::endl;printVptr();}void printVptr() override { std::cout << "Derived::printVptr, vptr = " << *(void **)this << std::endl; }int c;
};int main() {std::cout << "Base size: " << sizeof(Base) << std::endl;std::cout << "Derived size: " << sizeof(Derived) << std::endl;Base *obj = new Derived();std::cout << "before delete, this ptr is: " << obj << std::endl;delete obj;return 0;
}

编译运行结果:

Base size: 16
Derived size: 24
Base Constructor, this ptr: 0xa1a2c0
Base::printVptr, vptr = 0x401090
Derived Constructor, this ptr: 0xa1a2c0
Derived::printVptr, vptr = 0x401068
before delete, this ptr is: 0xa1a2c0
Derived Destructor, this ptr: 0xa1a2c0
Derived::printVptr, vptr = 0x401068
Base Destructor, this ptr: 0xa1a2c0
Base::printVptr, vptr = 0x401090

从结果中可以看到, 在执行Base部分的构造和析构时,vptr指向的是基类的虚表,执行Derived部分的构造和析构时,vptr指向的是派生类的虚表。

查看汇编代码,以Base的析构为例,其他的构造析构都是类似:

Base::~Base() [base object destructor]:pushq   %rbpmovq    %rsp, %rbpsubq    $16, %rspmovq    %rdi, -8(%rbp)             将this指针入栈movl    $vtable for Base+16, %edx  将虚表指针存入edxmovq    -8(%rbp), %rax             将this指针存入raxmovq    %rdx, (%rax)  将虚表指针存入rax指向的内存,也就是对象内存的开始部分,vptrmovl    $.LC1, %esimovl    $_ZSt4cout, %edicall    std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)movq    %rax, %rdxmovq    -8(%rbp), %raxmovq    %rax, %rsimovq    %rdx, %rdicall    std::basic_ostream<char, std::char_traits<char> >::operator<<(void const*)movl    $_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, %esimovq    %rax, %rdicall    std::basic_ostream<char, std::char_traits<char> >::operator<<(std::basic_ostream<char, std::char_traits<char> >& (*)(std::basic_ostream<char, std::char_traits<char> >&))movq    -8(%rbp), %raxmovq    %rax, %rdicall    Base::printVptr()nopleaveret

因此,整个构造析构的顺序为:

当new一个派生类对象时,首先会执行基类的构造函数,这时这个构造中的对象,其vptr指向基类的虚表,当基类部分构造完毕,继续执行派生类的构造函数时,此时对象的vptr指向派生类的虚表。

当delete这个派生类对象时,首先执行派生类的析构函数,此时对象的vptr仍然指向派生类的虚表,派生类的析构函数会继续执行基类的析构函数,此时对象的vptr会指向基类的虚表。最后派生类的析构函数会负责释放整个对象内存: call    operator delete(void*, unsigned long)

相关文章:

C++ 内存布局 - Part5: 继承关系中 构造析构与vptr的调整

这里以单继承为例&#xff0c;汇编采用AT&T格式&#xff0c;先看示例代码&#xff1a; #include <iostream>class Base { public:Base() {std::cout << "Base Constructor, this ptr: " << this << std::endl;printVptr();}virtual ~Ba…...

BUG-AttributeError: ‘EnforcedForest‘ object has no attribute ‘node‘

File “/home/adt/miniconda3/envs/bevdet/lib/python3.7/site-packages/trimesh/scene/transforms.py”, line 224, in nodes_geometry ‘geometry’ in self.transforms.node[n]): AttributeError: ‘EnforcedForest’ object has no attribute ‘node’ networkx 2.6.3 pyp…...

Spring Boot 3 配置 Redis 兼容单例和集群

配置项 Spring Boot 3.x 的 redis 配置和 Spring Boot 2.x 是不一样的, 路径多了一个data spring:...data:redis:host: redis.hostport: redis.portpassword: redis.passworddatabase: redis.database兼容单例和集群的配置 开发时一般用一个Redis单例就足够, 测试和生产环境…...

unsat钱包签名算法解析

unsat钱包签名算法解析 在数字货币领域&#xff0c;安全性是至关重要的&#xff0c;而签名算法则是确保交易和信息不可伪造的基础。本文将深入解析 unsat 钱包中使用的签名算法&#xff0c;重点关注如何生成和验证消息签名。 1. 签名算法概述 unsat 钱包使用 ECDSA&#xff…...

mysql删除唯一索引

推荐学习文档 golang应用级os框架&#xff0c;欢迎stargolang应用级os框架使用案例&#xff0c;欢迎star案例&#xff1a;基于golang开发的一款超有个性的旅游计划app经历golang实战大纲golang优秀开发常用开源库汇总想学习更多golang知识&#xff0c;这里有免费的golang学习笔…...

学习之面试题:偏函数

偏函数&#xff08;Partial Function&#xff09;是 Python 中的一个实用工具&#xff0c;通常用于函数式编程中&#xff0c;可以固定一个函数的部分参数&#xff0c;从而生成一个新的函数。偏函数在 Python 中通常通过 functools.partial 实现。在面试中&#xff0c;考察偏函数…...

面试技术点

Java 一、jvm模块 jvm是什么? 是一用用于计算设备的规范,虚构出来的计算机,在计算机上仿真模拟各种计算机功能来实现 jvm 作用是什么? java中所有类必须装载jvm中才能运行,这个装载工作有jvm装载器完成,.class类型文件能在jvm虚拟器中运行,但不能直接在系统中运行,需要…...

基础sql

在执行删除操作之前&#xff0c;建议先运行一个 SELECT 查询来确认你要删除的记录。这可以帮助你避免误删数据。 删除字段id默认值为空字符串的所有数据 delete from users where id ; 删除字段id默认值为null的所有数据 delete from users where id is null; 删除字段upd…...

Jenkins整合Docker实现CICD自动化部署(若依项目)

前期准备 提前准备好jenkins环境 并且jenkins能使用docker命令&#xff0c;并且已经配置好了jdk、node、maven环境&#xff0c;我之前写了安装jenkins的博客&#xff0c;里面讲得比较详细&#xff0c;推荐用我这种方式安装 docker安装jenkins&#xff0c;并配置jdk、node和m…...

kali chrome 安装 hackbar

HackBar 是一个用于在 Kali Linux 中快速测试 SQL 注入和 XSS 漏洞的 Chrome 扩展程序。以下是如何在 Kali Linux 上安装 HackBar 的步骤&#xff1a; 首先&#xff0c;你需要确保你的系统已经安装了 Google Chrome 或 Chromium。如果没有安装&#xff0c;你可以使用以下命令安…...

一文了解 Linux 系统的文件权限管理

文章目录 引入Linux文件权限模型查看文件权限权限信息解析修改文件权限符号模式八进制数字模式 引入 在Linux操作系统中&#xff0c;我们想查看我们对文件拥有哪些权限时&#xff0c;可以在终端键入ls -l或ll命令&#xff0c;终端会输出当前路径下的文件信息&#xff0c;如文件…...

Spark:DataFrame介绍及使用

1. DataFrame详解 DataFrame是基于RDD进行封装的结构化数据类型&#xff0c;增加了schema元数据&#xff0c;最终DataFrame类型在计算时&#xff0c;还是转为rdd计算。DataFrame的结构化数据有Row&#xff08;行数据&#xff09;和schema元数据构成。 Row 类型 表示一行数据 …...

Linux系统:本机(物理主机)访问不了虚拟机中的apache服务问题的解决方案

学习目标&#xff1a; 提示&#xff1a;本文主要讲述-本机(物理主机)访问不了虚拟机中的apache服务情况下的解决方案 Linux系统&#xff1a;Ubuntu 23.04&#xff1b; 文中提到的“本机”&#xff1a;代表&#xff0c;宿主机&#xff0c;物理主机&#xff1b; 首先&#xff0c…...

望繁信科技成功签约国显科技 流程挖掘助力制造业智造未来

近日&#xff0c;上海望繁信科技有限公司&#xff08;简称“望繁信科技”&#xff09;成功与深圳市国显科技有限公司&#xff08;简称“国显科技”&#xff09;达成合作。国显科技作为全球领先的TFT-LCD液晶显示及Mini/Micro LED显示产品供应商&#xff0c;致力于为笔记本、手机…...

枚举在Java体系中的作用

1. 枚举 枚举是在JDK1.5以后引入的。主要用途是&#xff1a;将一组常量组织起来&#xff0c;在这之前表示一组常量通常使用定义常量的方式&#xff1a; //用public static final修饰常量 public static final int RED 1; public static final int GREEN 2; public static f…...

『气泡水』Web官网 案例赏析

前言 Schweppes&#xff0c;作为一家享誉全球的气泡水品牌&#xff0c;致力于与年轻消费者建立更紧密的联系&#xff0c;并提升品牌影响力。为此&#xff0c;其打造了一个充满创意和高度互动性的官网&#xff0c;利用前端技术和动画效果&#xff0c;将产品特性与用户浏览体验完…...

【前端】制作一个简单的网页(2)

单标签组成的元素 这类标签不需要内容产生效果&#xff0c;通常表示对网页的某种行为&#xff0c;它们不用标记任何内容&#xff0c;开始即是结束。 比如&#xff0c;<hr>标签的作用是在网页中添加一条分割线&#xff0c;它仅包含开始标签&#xff0c;是一个单标签元素。…...

OpenAI Canvas:提升编程与写作效率的全新工作界面

随着人工智能技术的飞速发展&#xff0c;大语言模型&#xff08;LLM&#xff09;不仅限于生成文本&#xff0c;还能逐步扩展至编程、设计等任务的支持。近期&#xff0c;OpenAI 推出了一个名为 Canvas 的全新功能&#xff0c;专门用于协助用户进行编程和写作。这一功能与 Claud…...

将SpringBoot的Maven项目打成jar包和war包

先需要明确的是&#xff0c;该项目打包的形态是可执行的jar包&#xff0c;还是在tomcat下运行的war包。 springboot自带的maven打包 1.创建一个springboot web项目 1.api控制层HelloWorld.java RestController RequestMapping("/hello") public class HelloWorld …...

【Iceberg分析】Spark与Iceberg集成之常用存储过程

文章目录 Spark与Iceberg集成之常用存储过程调用语法调用样例表快照管理快照回滚根据snapshotid进行回滚根据timestamp进行回滚 设置表当前生效的快照 表元数据管理设置快照过期时间清除孤岛文件重写数据文件运用参数示例optionsGeneral OptionsOptions for sort strategyOptio…...

循证研发怎么做?五阶段路径S、A、B、C分级,2026团标给出量化答案

2026年&#xff0c;在博鳌健康食品科学大会暨博览会上&#xff0c;一项由仙乐健康WelMax联合中国保健协会食物营养与安全专业委员会、拜耳、赫力昂等机构共同制定的团体标准正式亮相。该标准编号为T/CS 283-2026&#xff0c;全称为《营养健康产品循证研发技术规范》&#xff0c…...

构建个人技能图谱:从GitHub项目到结构化能力管理实践

1. 项目概述&#xff1a;一个技能图谱的构建与价值 最近在整理自己的技术栈时&#xff0c;发现了一个挺有意思的GitHub项目&#xff0c;标题是“headlike-oradexon12/skills”。乍一看&#xff0c;这像是一个个人技能仓库&#xff0c;但深入探究后&#xff0c;我发现它远不止是…...

JAVA练习:单一职责原则重构

问题背景原始Login类同时承担界面展示、登录校验、数据库连接、用户查询、程序入口多重职责&#xff0c;功能高度耦合&#xff0c;违反单一职责原则&#xff08;一个类只负责一类功能&#xff09;&#xff0c;修改某部分功能易影响其他模块。重构思路按职责拆分&#xff0c;分为…...

地理学者必抢的AI协同时代入场券:NotebookLM+QGIS工作流搭建指南(仅限首批内测用户验证版)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;NotebookLM地理学研究辅助的范式革命 从静态文献到动态知识图谱 NotebookLM 通过语义切片与向量对齐技术&#xff0c;将地理学经典文献&#xff08;如《人文地理学导论》《自然地理学原理》&#xff…...

控制理论实践:从PID到MPC的Python实现与仿真调试

1. 项目概述&#xff1a;从“Gonzo”看控制理论在开源项目中的实践最近在GitHub上看到一个挺有意思的项目&#xff0c;名字叫“control-theory/gonzo”。光看这个标题&#xff0c;你可能会有点摸不着头脑——“控制理论”和“Gonzo”有什么关系&#xff1f;Gonzo这个词&#xf…...

Stardew Valley Mod开发:使用OpenClaw主题框架快速构建原生风格UI

1. 项目概述&#xff1a;一个为Stardew Valley Mod开发者量身打造的主题框架如果你是一位《星露谷物语》&#xff08;Stardew Valley&#xff09;的模组&#xff08;Mod&#xff09;开发者&#xff0c;或者正打算踏入这个充满创造力的社区&#xff0c;那么你很可能已经体会过&a…...

Linux系统下英特尔Arc显卡驱动安装与AI推理性能调优实战

1. 英特尔Arc显卡在Linux下的独特优势 第一次在Linux系统上折腾英特尔Arc显卡时&#xff0c;我完全被它的性价比震惊了。作为长期使用N卡的开发者&#xff0c;原本只是抱着试试看的心态&#xff0c;结果发现这套组合在AI推理任务中表现远超预期。不同于Windows系统开箱即用的体…...

如何高效管理命令历史:yargs readline功能的终极指南

如何高效管理命令历史&#xff1a;yargs readline功能的终极指南 【免费下载链接】yargs yargs the modern, pirate-themed successor to optimist. 项目地址: https://gitcode.com/gh_mirrors/ya/yargs 在现代命令行工具开发中&#xff0c;提供流畅的用户交互体验至关…...

如何快速掌握Git和GitHub:新手入门终极指南

如何快速掌握Git和GitHub&#xff1a;新手入门终极指南 【免费下载链接】hello-git Curso para aprender a trabajar con el sistema de control de versiones Git y la plataforma GitHub desde cero y para principiantes. 项目地址: https://gitcode.com/gh_mirrors/he/he…...

PPTAgent终极指南:如何5分钟完成专业演示文稿的AI智能生成

PPTAgent终极指南&#xff1a;如何5分钟完成专业演示文稿的AI智能生成 【免费下载链接】PPTAgent An Agentic Framework for Reflective PowerPoint Generation 项目地址: https://gitcode.com/gh_mirrors/pp/PPTAgent 你是否曾为制作演示文稿而熬夜加班&#xff1f;是否…...