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

C++的显示类型转换和隐式类型转换

C++的显示类型转换和隐式类型转换

显示类型转换包括静态转换(static_cast)、动态转换(dynamic_cast)、常量转换(const_cast)、重新解释转换(reinterpret_cast)

1.静态转换(static_cast)

1.1一句话说清

static_castC++ 最常用、最安全、编译期完成的类型转换运算符,用于合法的、有意义的类型转换

它是编译期检查,不会做运行时检查,比 C 语言强转 (type)val 更安全。

1.2 能做什么(最常用场景)

1.2.1 基本数据类型转换

int a = 10;
double b = static_cast<double>(a); // int → double

1.2.2 有继承关系的 向上转型(安全)

派生类 → 基类(指针 / 引用)

Derived* d = new Derived();
Base* b = static_cast<Base*>(d); // ✅ 安全

1.2.3 空指针转换

void* p = nullptr;
int* q = static_cast<int*>(p);

1.2.4 显式调用单参数构造函数 / 转换函数

string s = static_cast<string>("hello");

1.2.5 把表达式转为右值(配合移动语义)

int a = 10;
int&& b = static_cast<int&&>(a);

1.3 不能做什么(绝对不行)

1.3.1 不能用于 向下转型(不安全)

基类 → 派生类,static_cast 不检查是否真的是该对象

Base* b = new Base();
Derived* d = static_cast<Derived*>(b); // ❌ 编译过,但运行会炸

👉 向下转型必须用 dynamic_cast

1.3.2 不能去掉 const

const int a = 10;
int* p = static_cast<int*>(&a); // ❌ 编译错误

👉 去 const 必须用 const_cast

1.3.3 无关类型之间强转

int* p = static_cast<int*>(100); // ❌ 错误

👉 这种底层强转要用 reinterpret_cast

1.4 核心特点(必须记住)

  1. 编译期转换,没有运行时开销
  2. 只允许合法、有意义的转换
  3. 向上转型(派生→基类)非常安全
  4. 比 C 风格强转 (type) 更安全、更清晰
  5. 不能做动态检查、不能去 const、不能乱转指针

1.5 和其他转换的区别(超级好记)

转换 用途
static_cast 正常、安全、编译期转换
dynamic_cast 继承类向下转型(运行时检查)
const_cast 去掉 / 添加 const
reinterpret_cast 底层二进制强转(危险)

1.6 最简单记忆口诀

  • static_cast 最安全,
  • 基本类型继承转
  • 不能去 const 不能乱转
  • 向下转型别用它

2.动态转换(dynamic_cast)

2.1 基本作用

dynamic_cast 是 C++ 专门用于多态类型转换的运算符,主要做:

  • 基类指针 / 引用 → 派生类指针 / 引用(向下转型)
  • 也可以做横向转换(同一继承树内的兄弟类)

它是唯一一个在运行时做检查的类型转换。

2.2 核心前提(必须满足)

要使用 dynamic_cast,基类必须包含至少一个虚函数(要有虚表、支持多态),否则编译报错。

2.3 两种用法 & 结果

2.3.1 指针转换

Base* base_ptr = new Derived();// 尝试转成 Derived*
Derived* der_ptr = dynamic_cast<Derived*>(base_ptr);
  • 转换成功:返回有效指针
  • 转换失败:返回 nullptr

2.3.2 引用转换

Base& base_ref = derived_obj;
Derived& der_ref = dynamic_cast<Derived&>(base_ref);
  • 成功:返回派生类引用
  • 失败:抛出 std::bad_cast 异常

引用没有 “空引用”,所以失败只能抛异常。

2.4 安全 vs 不安全

  • static_cast 向下转型:

    不检查,直接强转,错了也不知道 → 不安全

  • dynamic_cast 向下转型:

    运行时查真实类型 → 安全

2.5 适用场景

  • 你拿到一个基类指针 / 引用,但不确定它实际指向哪个子类
  • 需要调用只有子类才有的成员函数
  • 框架、插件、多态对象管理中大量使用

2.6 典型示例

class Base {
public:virtual ~Base() {}  // 必须有虚函数
};class Derived : public Base {};int main() {Base* b = new Derived;Derived* d = dynamic_cast<Derived*>(b);if (d) {// 转换成功} else {// 不是 Derived 类型}
}

2.7 一句话总结

  • dynamic_cast = 运行时安全向下转型
  • 必须有多态(虚函数)
  • 指针失败返回 nullptr,引用失败抛异常

3.常量转换(const_cast)

3.1 作用只有一个

用于增加或去除指针 / 引用上的 const、volatile 限定

不能改变类型,只能改 “常量性”。

3.2 只能用于

  • 指针
  • 引用
  • 指向对象的成员指针

不能用于普通变量。

3.3 最常见用法:去掉 const

const int a = 10;
const int* p = &a;// 去掉 const
int* q = const_cast<int*>(p);
void func(const int& x) {// 内部需要修改时int& m = const_cast<int&>(x);
}

3.4 也可以增加 const

int x = 10;
int* p = &x;const int* q = const_cast<const int*>(p);

3.5 重要危险规则

  • const_cast 本身是安全的
  • 修改原本就是 const 的对象是未定义行为
const int a = 10;
int* p = const_cast<int*>(&a);
*p = 20; // ❌ 未定义行为!可能崩溃、可能不变

只有原本不是 const 的对象,去掉 const 再修改才安全:

int x = 10;
const int* pc = &x;
int* p = const_cast<int*>(pc);
*p = 20; // ✅ 安全

3.6 一句话记忆

const_cast 只改常量性,不改类型;

能加能去 const,只对指针引用;

改真 const 对象 = 未定义行为。

4.重新解释转换(reinterpret_cast)

reinterpret_cast = 重新解释二进制内存

它不做任何计算、不检查、不转换值,只把一段内存强行当成另一种类型看

4.1 一句话核心

  • 最暴力、最危险、最接近 C 语言强转 (type)
  • 只改变编译器怎么看待这段内存,不改变内存本身
  • 用于底层、系统、硬件、网络、指针地址操作

4.2 典型用法

① 无关指针类型互转

int a = 0x12345678;
int* p = &a;// 把 int* 强行看成 char*
char* c = reinterpret_cast<char*>(p);

② 指针 ↔ 整数互转(地址操作)

int x = 10;
// 指针 → 整数(地址值)
uint64_t addr = reinterpret_cast<uint64_t>(&x);// 整数 → 指针
int* q = reinterpret_cast<int*>(addr);

③ 函数指针强转

void (*fp)() = nullptr;
// 强行看成另一种函数指针
using Func = int(*)(int);
Func f = reinterpret_cast<Func>(fp);

4.3 特点(必须记住)

  1. 编译期完成,无运行时开销
  2. 几乎不做安全检查,转错就炸
  3. 不修改二进制数据,只改 “解释方式”
  4. 不可用于:
    • 直接转普通数值(如 int→double)
    • 去掉 const(必须用 const_cast)

4.4 适用场景(正经用途)

  • 操作系统、驱动、嵌入式开发
  • 网络协议解析(字节流转结构体)
  • 内存布局操作、hook、注入
  • 与 C 接口、硬件寄存器交互

日常业务代码几乎不应该用

4.5 一句话记忆

reinterpret_cast 不转值,只改内存解释;

指针随便转,地址转整数;

高效但危险,只用于底层。

http://www.jsqmd.com/news/710369/

相关文章:

  • 2026年改灯车灯透镜推荐榜:市场分析与四款标杆产品深度解读#马瑞利透镜#树懒舒透镜 - Reaihenh
  • HTTPie CLI与Bash脚本:10个命令行自动化终极技巧
  • 上海别墅新古典风格落地指南:从比例控制到材质搭配的工程化方法
  • 2026重庆黄金回收机构排行榜(实测靠谱) 诚鑫名品依旧遥遥领先 - 品牌企业推荐师(官方)
  • XTuner V1:专为超大规模MoE模型设计的高效训练引擎
  • Python深度学习实战:Keras与TensorFlow 2.x快速入门
  • 2026年桂林靠谱中介大揭秘,哪家才是你的最佳之选? - 品牌企业推荐师(官方)
  • 华硕笔记本性能调优终极指南:用G-Helper释放硬件全部潜力
  • Confucius Code Agent架构解析与性能优化
  • 2026选对太阳能路灯厂家,这三点最值得细看 - 品牌企业推荐师(官方)
  • 别墅全屋热水零等待方案:回水管设计、泵阀选型与定时策略实测
  • Viper配置别名系统:灵活的参数重命名方案终极指南
  • 企业级AI平台实战:Open WebUI私有化部署深度解析
  • PlaceHolderView性能优化指南:避免常见陷阱的7个策略
  • 高级内存注入技术实现原理:PE加载器与进程管理架构解析
  • 如何实现Spring Boot消息顺序消费:完整指南与实战方案
  • OGG修改表结构操作步骤
  • 电脑上不了网怎么修?5 个通用技巧,快速解决网络连接异常
  • 三步搞定网页视频下载:猫抓插件让资源嗅探如此简单
  • sofa-pbrpc HTTP协议支持与Web监控:一站式运维管理工具
  • 高效提取Wallpaper Engine资源:RePKG工具深度使用指南
  • DeepSeek Claw:命令行AI助手集成与OpenClaw框架实战指南
  • Yew架构设计:模块化和可扩展性的终极指南
  • 养生馆怎么用AI做体质辨识 - 品牌企业推荐师(官方)
  • 别墅庭院施工中,这5个结构隐患比设计翻车更致命
  • Mathsteps根式运算:掌握n次方根的简化与乘法
  • 别再硬碰硬了!用Python+ROS2手把手实现机器人导纳控制(附UR5e仿真代码)
  • 双机械臂视觉规划与协同控制关键技术解析
  • ADAMAS:稀疏注意力优化技术解析与应用实践
  • MCHPRS核心组件源码剖析:深入理解红石编译和执行流程