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

void*指针类型转换笔记

void*指针类型转换笔记

#include <iostream>// 基类1
class Base1 {
public:int x;Base1() : x(100) {}
};// 基类2
class Base2 {
public:int y;Base2() : y(200) {}
};// 派生类(你要求叫 Sub)
class Sub : public Base1, public Base2 {
public:int z;Sub() : z(300) {}
};int main() {// 1. 创建 Sub 对象Sub obj;Sub* src = &obj;// 2. 转成 void*void* p = src;// 3. 从 void* 转回 Base2*Base1* base1    = (Base1*)p;     // base1 多重继承的第一个基类,没有偏移量,虽然正确,但是显示中也是存在风险的,不建议这么用Base2* base2    = (Base2*)p;     // base2 多重继承的第二个基类,偏移量错了,将base1的空间赋给Base2指针了,本例中不会有问题,因为一开始也是个int内存空间,但现实中会调至不可预测的结果Base2* base3    = (Base2*)src;   // 有类型的src指针转基类指针,会自动找到正确的Base2偏移量,使基类指针可以正确使用。// 使用static_cast转部分编译会报错// Base1* base1    = static_cast<Base1*>(p);     // base1 多重继承的第一个基类,没有偏移量,虽然正确,但是显示中也是存在风险的,不建议这么用// Base2* base2    = static_cast<Base2*>(p);     // base2 多重继承的第二个基类,偏移量错了,将base1的空间赋给Base2指针了,本例中不会有问题,因为一开始也是个int内存空间,但现实中会调至不可预测的结果// Base2* base3    = static_cast<Base2*>(src);   // 有类型的src指针转基类指针,会自动找到正确的Base2偏移量,使基类指针可以正确使用。Sub*   dst  = static_cast<Sub*>(p);// 4. 验证:是否能正确访问 y?std::cout << "obj    address: " << src   << std::endl;std::cout << "sub    address: " << dst   << std::endl;std::cout << "base1  address: " << base1 << std::endl;std::cout << "base2  address: " << base2 << std::endl;std::cout << "base3  address: " << base3 << std::endl; // 可以虽然将src赋值给base3,但是两个指针的地址并不相同,是因为转父类指针时,自动填上将了便宜量,本例子中是4个字节。// 5. 输出变量std::cout << "src[x:" << src->x << ", y:" << src->y << ", z:" << src->z << "]" << std::endl;std::cout << "dst[x:" << dst->x << ", y:" << dst->y << ", z:" << dst->z << "]" << std::endl;std::cout << "base1[x:" << base1->x << "]" << std::endl; // base1没有偏移量,虽然正确,但是存在风险,不建议用std::cout << "base2[y:" << base2->y << "]" << std::endl; // 此处可以看到,base2的值其实是base1的内存空间,存的是值是100std::cout << "base3[y:" << base3->y << "]" << std::endl; // 带类型的转换,数据正确, 所以我们的指针如果转成void*,如果想用,我们需要将其转成其真实的类型指针再使用. 如果真的需要基类指针,转成原始类型指针后再转基类指针,就可以诡辩风险。return 0;
}

总结:

类对象指针转成 void* 后,若要还原,必须先转回原始类指针,再通过 static_cast 转为基类指针。
禁止直接将 void* 强转为非首基类指针,否则指针偏移错误,访问将导致未定义行为。

http://www.xdnf.cn/news/19930.html

相关文章:

  • C++ const以及相关关键字
  • Ubuntu 25.04搭建hadoop3.4.1集群详细教程
  • Access开发导出PDF的N种姿势,你get了吗?
  • 开源本地LLM推理引擎(Cortex AI)
  • OpenTenBase vs MySQL vs Oracle,企业级应用数据库实盘对比分析
  • 使用国外网络的核心问题有哪些?
  • 基于 epoll 的高并发服务器原理与实现(对比 select 和 poll)
  • 十七、单线程 Web 服务器
  • (自用)PowerShell常用命令自查文档
  • AI重构出海营销:HeadAI如何用“滴滴模式”破解红人营销效率困局?
  • Flink 网络消息队列 PrioritizedDeque
  • C52单片机独立按键模块,中断系统,定时器计数器以及蜂鸣器
  • OpenLayers常用控件 -- 章节三:鼠标位置坐标显示控件教程
  • 多线程入门到精通系列: 从操作系统到 Java 线程模型
  • 快鹭云业财一体化系统技术解析:低代码+AI如何破解数据孤岛难题
  • 飞算JavaAI开发在线图书借阅平台全记录:从0到1的实践指南
  • 【C++】详解形参和实参:别再傻傻分不清
  • Android adb shell命令分析应用内存占用
  • 2025全国大学生数学建模C题保姆级思路模型(持续更新):NIPT 的时点选择与胎儿的异常判定
  • Trae + MCP : 一键生成专业封面——从概念到落地的全链路实战
  • java对接物联网设备(一)——使用okhttp网络工具框架对接标准API接口
  • SVN和Git两种版本管理系统对比
  • Hunyuan-MT-7B模型介绍
  • 使用Vue.js和WebSocket打造实时库存仪表盘
  • window使用ffmep工具,加自定义脚本执行视频转码成h264(运营人员使用)
  • P13929 [蓝桥杯 2022 省 Java B] 山 题解
  • 第三方网站测评:【WEB应用文件包含漏洞(LFI/RFI)的测试步骤】
  • 神经网络模型介绍
  • LeetCode 3132.找出与数组相加的整数2
  • 机器学习算法在Backtrader策略稳定性中的作用分析