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

17.C++类型转换

1. C语言中的类型转换

        在C语言中,如果赋值运算符左右两侧类型不同,或者形参与实参类型不匹配,或者返回值类型与接收返回值类型不一致时,就需要发生类型转换,C语言中共有两种形式的类型转换:隐式类型转换和显式类型转换。

1.隐式类型转换:编译器在编译阶段自动进行,能转就转,不能转就编译失败

2.显时类型转换:需要用户自己处理

缺陷:转换的可视性较差,所有的转换类型都是用一种相同的形式书写,难以跟踪错误的转换。


2. 为什么C++需要四种类型转换

 解决C风格类型转换的缺陷

C语言中的类型转换存在以下问题:

  • 缺乏安全性检查:如父类指针强制转换为子类指针时,可能指向非子类对象,导致内存越界。
  • 语义模糊:所有转换都用同一语法(如(int*)),难以区分不同场景(如常量性修改、类层次转换等),代码可读性差。
  • 隐式风险:例如将const指针转为非const指针,可能导致未定义行为,但编译器不会警告。

C++要兼容C语言,所以C++还可以使用C语言的转换风格。

3. C++强制类型转换

通过四种专用操作符,限制转换场景并引入安全检查:

  • static_cast:用于安全的隐式转换(如基本类型转换、类层次上行转换),禁止无关类型转换(如int*double*)。
  • dynamic_cast:在类层次下行转换时进行运行时类型检查(需父类有虚函数),失败返回nullptr或抛出异常,避免非法访问。
  • const_cast:明确用于修改constvolatile属性,避免意外修改常量对象。
  • reinterpret_cast:低级别位模式转换(如指针转整数),明确标识高风险操作。

3.1 static_cast

基本类型转换

double d = 3.14;
int i = static_cast<int>(d);  // 显式截断小数部分 

编译器隐式执行的任何类型转换都可用static_cast,但它不能用于两个不相关的类型进行转换

以下类型被视为相关类型(Related Types),可安全使用static_cast

  • 同一继承链的类(基类↔派生类)
  • 基本数值类型互转(如intdoublefloatlong
  • 用户定义转换支持的类型(通过构造函数或operator重载)
  • void*与其他对象指针(需显式指明目标类型)

什么叫不相关的类型

  • 无继承关系:不在同一个类层次结构中(非基类与派生类)。
  • 无标准转换规则支持:无法通过隐式转换或用户定义的转换函数建立联系。
  • 内存布局不兼容:类型的大小、对齐方式或二进制表示差异较大。
class A {};
class B {};
 
A* a = new A();
// B* b = static_cast<B*>(a);  // 编译错误:A与B无继承关系 

int x = 10;
int* p = &x;
// double* dp = static_cast<double*>(p);  // 编译错误:int*与double*无关联 

struct Vec3 { float x, y, z; };
// int n = static_cast<int>(Vec3{1,2,3});  // 编译错误:无用户定义的转换规则 

3.2 reinterpret_cast

用于将一种类型转换成另一种不同的类型:

int* p = new int(42);
uintptr_t addr = reinterpret_cast<uintptr_t>(p);  // 地址转整数 

3.3 const_cast

最常用的用途就是删除变量的const属性,方便赋值

const int x = 10;
int* px = const_cast<int*>(&x);  // 语法允许 
*px = 20;                        // 未定义行为!x可能存储在只读内存 

3.4 dynamic_cast

用于将一个父类对象的指针/引用转换为子类对象的指针或引用(动态转换)

dynamic_cast 是 C++ 中**唯一依赖运行时类型信息(RTTI)的类型转换操作符,专用于处理 类层次结构中的多态类型安全转换。其核心逻辑为:

  1. 运行时类型检查:通过查询对象的虚函数表(vtable)获取实际类型信息,验证目标类型是否与对象真实类型兼容。
  2. 安全失败机制:若转换不合法(如父类对象并非目标子类实例),指针转换返回 nullptr,引用转换抛出 std::bad_cast 异常。
  3. 多态性依赖:要求基类至少有一个虚函数(否则无法生成虚表,编译报错)。
class Animal { 
public:
    virtual ~Animal() {}  // 必须至少有一个虚函数 
};
class Dog : public Animal { 
public: 
    void bark() { /* 子类特有方法 */ } 
};
 
Animal* animal = new Dog();  // 多态指针 
Dog* dog = dynamic_cast<Dog*>(animal);  // 合法:animal实际指向Dog对象 
if (dog) dog->bark();  // 安全调用子类方法 
class A { virtual ~A() {} };
class B : public A {};
class C : public A {};
 
A* obj = new B();
C* c = dynamic_cast<C*>(obj);  // 返回nullptr,因obj实际是B类型 

A类对象obj并非C类实例,而是B类实例

转换类型典型场景安全检查性能开销使用频率
static_cast类型关联明确的转换编译期检查⭐⭐⭐⭐
dynamic_cast多态类型下行转换运行时检查较高⭐⭐
const_cast常量性/易变性修改
reinterpret_cast底层内存重解释

相关文章:

  • DeepSeek 开源周:DeepEP 项目详解,GPU 压榨计划启动!
  • 基于javaweb的SpringBoot健身房管理系统设计和实现(源码+文档+部署讲解)
  • 猿大师播放器:智慧交通Web网页低延迟播放监控RTSP H.265视频解决方案
  • 蓝桥杯之日期题
  • 【项目测试】博客系统—Selenium自动化测试、编写测试用例
  • JavaScript函数
  • 虚拟机 | Ubuntu 安装流程以及界面太小问题解决
  • 终端指令后续和shell脚本编程
  • linux 设置tomcat开机启动
  • Java包装类性能优化:深入解析Integer享元模式的源码实现
  • 一文掌握Selenium的详细使用
  • OpenCloudOS Server 9 安装openssl 1.1.x
  • 5个GitHub热点开源项目!!
  • 多媒体常用概念
  • 双重因子认证:守护数字安全的“双保险”
  • 我的AI工具箱Tauri版-FluxCharacterGeneration参考图像生成人像手办(Flux 版)
  • 在Isaac_sim图形化界面中进行截图的方法
  • JAVA面试常见题_基础部分-(1)
  • 2024年国赛高教杯数学建模D题反潜航空深弹命中概率问题解题全过程文档及程序
  • 存储产品和数据库产品之间有没有竞争关系
  • 佛山网站建设开发/360关键词排名百度
  • 如何做收款网站/seo查询工具有哪些
  • 对做网站公司的疑问/百度灰色词优化排名
  • 网站源码下载地址是什么/外贸推广引流
  • 注册公司网站多少钱/上线了建站
  • 手机网站集成支付宝/app如何推广