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

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.dtcms.com/a/366708.html

相关文章:

  • SpringBoot中 Gzip 压缩的两种开启方式:GeoJSON 瘦身实战
  • k8s基础(未完待续)
  • 拜占庭攻击与投毒攻击
  • Linux编写shell脚本,输入多个原文件名和新文件名,一次对多个文件重命名
  • 2025亚马逊卖家防恶搞指南:揪出恶意套路,3招守住店铺安全
  • Gmail 数据泄露安全警报以及启示
  • 23种设计模式——抽象工厂模式(Abstract Factory Pattern)详解
  • C++开发中的常用设计模式:深入解析与应用场景
  • Nginx 实战系列(一)—— Web 核心概念、HTTP/HTTPS协议 与 Nginx 安装
  • 移远EC200A OpenCPU笔记
  • 【bash】命令查看当前目录下文件个数
  • STM32G4 速度环开环,电流环闭环 IF模式建模
  • 发票、收据合并 PDF 小程序,报销上传 3 秒搞定
  • Beautiful.ai:AI辅助PPT工具高效搞定排版,告别熬夜做汇报烦恼
  • Redis的过期策略和Redis 内存淘汰策略
  • Uni-App + Vue onLoad与onLaunch执行顺序问题完整解决方案 – 3种实用方法详解
  • 【系统架构设计(13)】项目管理上:盈亏平衡分析与进度管理
  • android seekbar显示刻度
  • 深入内核交互:用 strace 看清 Android 每一个系统调用
  • Android实战进阶 - 富文本
  • iPhone17再爆猛料?苹果2025秋季发布会亮点抢先看
  • 北斗导航 | Android Studio开发NMEA0183上位机的技术方案
  • 邮件如何防泄密?这10个电子邮件安全解决方案真的好用,快收藏
  • 02-Media-4-mp4muxer.py 录制视频并保存为MP4文件的示例
  • 2025年数学建模国赛C题第二版本超详细解题思路
  • Android adb shell命令分析应用内存占用
  • 公司机密视频泄露频发?如何让机密视频只在公司内部播放
  • 硬件开发1-51单片机3-串口
  • 【Bluedroid】 A2DP Source 音频会话终止流程解析(btif_a2dp_source_end_session)
  • MySQL数据库和SQL语言