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

C++ 强制类型转换

C++ 四大强制类型转换

转换类型使用范围访问权限继承关系要求多态支持额外说明
static_cast适用于相关类型之间的转换,如基类<->派生类指针转换、数值类型转换等需满足访问权限(如基类继承方式)必须有继承关系,且访问权限允许可用于多态类型,但不做运行时检查编译时转换,效率高,但对非法转换不安全,向下转型可能导致未定义行为
dynamic_cast用于多态类型的安全向下转型或跨类层次指针转换需满足访问权限必须是多态类(含虚函数),有继承关系支持,执行运行时类型检查转换失败时,指针返回 nullptr,引用抛异常,性能开销较大
const_cast用于去除或添加 const / volatile 修饰无访问权限限制不依赖继承关系不涉及多态只能修改类型修饰符,不能改变类型本质,去除 const 后修改对象导致未定义行为
reinterpret_cast任意类型指针或整数间的转换,极其底层和不安全无访问权限限制不要求继承关系不支持不安全,直接按二进制重新解释,通常用于系统底层、硬件交互等特殊场景,慎用

static_cast

编译期类型检查,适合“已知关系”的转换

error C2440: “static_cast”: 无法从“B *”转换为“A *”, 需要存在寄存关系

class A {};
class B {};
int main()
{B b;A* a = static_cast<A*>(&b);
}

reinterpret_cast

完全底层强转,仅改变解释方式,不改地址内容
不能用于普通类型转换,例如:int → float (float、int底层内存解析不一样)

const_cast

去除 const,解除只读属性

dynamic_cast

支持多态转换,需有虚函数,需要RTTI(运行阶段类型识别)
dynamic_cast运算符将使用一个指向基类的指针来生成一个指向派生类的指针;否则,该运算符返回0(空指针);

典型实现步骤
当执行 dynamic_cast<DestType*>(srcPtr) 时,编译器生成的底层代码大致会做以下操作:

  • (1) 检查空指针
    如果 srcPtr 是 nullptr,直接返回 nullptr。
  • (2) 检查静态类型兼容性
    如果 DestType 和 srcPtr 的静态类型(编译时类型)无关(非继承关系),直接返回 nullptr。
  • (3) 查询 RTTI
    通过 srcPtr 对象的虚函数表(vtable)找到其 RTTI 信息(通常是 type_info 结构体),获取实际对象的动态类型。
  • (4) 遍历继承树
    向下转型(Downcast):检查 DestType 是否是实际对象的基类或派生类。如果是派生类,计算指针偏移量并调整。
    侧向转型(Crosscast):在多重继承中,可能需要调整指针指向目标类的子对象。
  • (5) 返回结果
    如果类型兼容,返回调整后的指针。否则,返回 nullptr。
class B1 {
public:virtual void f1() {}int b1_data;
};class B2 {
public:virtual void f2() {}int b2_data;
};class D : public B1, public B2 {
public:virtual void f1() override {} // 覆盖 B1::f1virtual void fd() {}          // D 的新虚函数int d_data;
};
int main()
{B2* d = new B2();B1* pb2 = dynamic_cast<B1*>(d);D* pb2s = static_cast<D*>(d);
}

pb2 不能转换成功,创建的B2类型不能转成B1类型
pb2s 能转换成功,但是运行的时候会产线未定义行为,因为分内存的时候只是分配了B2的内存大小,但是强制转成D,变成使用了D的内存大小,可能会访问非法内存

下图:
pb2s直接按编译向前减了8个字节(static_cast编译器的时候就进行转换了)
在这里插入图片描述

问题

为什么 static_cast 能正确处理多继承向上转型?

(1) 编译器已知继承关系
在编译时,编译器 完全知道 Derived 的继承结构(包括基类的顺序和偏移量)。
static_cast 直接根据继承关系计算指针调整,无需运行时信息。

(2) 指针调整是确定的
在多继承中,基类子对象的偏移量是编译期常量。例如:
Base1 的偏移量 = 0(首个子对象)。
Base2 的偏移量 = sizeof(Base1)。
static_cast 会根据目标基类类型,自动计算正确的偏移量。

(3) 不涉及运行时类型检查
static_cast 不依赖 RTTI(Run-Time Type Information),完全在编译期完成转换。
因此,即使没有虚函数(无虚表),static_cast 也能正确工作。

对比 dynamic_cast

dynamic_cast 也能向上转型,但它是为 向下转型(Downcasting) 设计的,向上转型时会退化为 static_cast:
dynamic_cast 的向上转型没有额外作用,反而可能误导代码读者(让人误以为需要运行时检查)。
static_cast 更清晰、更高效。

Base1* pb1 = dynamic_cast<Base1*>(&d); // 等价于 static_cast

为什么 static_cast 不能安全用于向下转型?

虽然 static_cast 能正确处理向上转型,但 向下转型(Downcasting) 时存在风险:
static_cast 不会检查 pb2 是否真的指向 Derived 对象,直接按继承关系调整指针,可能导致非法内存访问。此时必须用 dynamic_cast:

Base2* pb2 = new Base2;  // 纯 Base2 对象
Derived* pd = static_cast<Derived*>(pb2); // 危险!
http://www.xdnf.cn/news/15264.html

相关文章:

  • 前端性能优化利器:懒加载技术原理与最佳实践
  • QuickUnion优化及Huffman树
  • flask校园学科竞赛管理系统-计算机毕业设计源码12876
  • 使用docker的常用命令
  • 【C++】第十五节—一文详解 | 继承
  • 接入Deepseek的AI截图全能王—截图、录屏剪辑的工具,支持AI OCR / 识图 /翻译
  • Vue3 Diff 算法片段解析:新旧节点队列之乱序比对与更新策略
  • Java使用Langchai4j接入AI大模型的简单使用(五)--流式输出的实现
  • 设计模式之单例模式:深入解析全局唯一对象的艺术
  • STM32-第五节-TIM定时器-1(定时器中断)
  • F-GNN的新型检测框架:随机森林增强图神经网络
  • Python 数据建模与分析项目实战预备 Day 4 - EDA(探索性数据分析)与可视化
  • 音视频学习(三十七):pts和dts
  • 香港理工大学实验室定时预约
  • php生成二维码
  • Java网络编程
  • ref 和 reactive
  • 详解Linux下多进程与多线程通信(一)
  • Kafka——Kafka 线上集群部署方案怎么做?
  • 解决 Python 跨目录导入模块问题
  • git实际工作流程
  • Java 大视界 -- Java 大数据在智能教育学习资源智能分类与标签优化中的应用(346)
  • [2025CVPR]DenoiseCP-Net:恶劣天气下基于LiDAR的高效集体感知模型
  • 若依框架集成阿里云OSS实现文件上传优化
  • 基于requests_html的爬虫实战
  • 「小程序开发」项目结构和页面组成
  • java: DDD using oracle 21c
  • 多级@JsonTypeInfo和@JsonSubTypes注解使用详解及场景分析
  • opencv python 基本操作
  • Python自动化:每日销售数据可视化