【C++】告别“类型转换”踩坑,从基础到四种核心强制转换方式

【C++】告别“类型转换”踩坑,从基础到四种核心强制转换方式

各位大佬好,我是落羽!一个坚持不断学习进步的学生。
如果您觉得我的文章还不错,欢迎多多互三分享交流,一起学习进步!
也欢迎关注我的blog主页:
落羽的落羽

文章目录

一、回顾C语言的类型转换

C语言的类型转换主要是隐式类型转换和强制类型转换:

  • 隐式类型转换,是编译器在特定情况下自动进行的类型转换,通常发生在不同类型的表达式运算中。主要是整型之间、整型与浮点型之间、浮点型之间的转换。
int a =1;double b =2.234; a = b;
  • 强制类型转换:是我们通过显式语法手动指定的类型转换,主要是整型和指针、指针和指针之间的转换。
int a =1;char* p =(char*)a;int* p1 =(int*)malloc(sizeof(int));

但是,并非所有类型直接都能转换。例如double就无法转为指针类型。

在这里插入图片描述

二、C++中的类型转换

1. 内置类型转为自定义类型

随着自定义类型的广泛使用,C++也支持了内置类型和自定义类型之间的相互转换:

  • 内置类型转换为自定义类型,需要自定义类型的相关构造函数支持。非常好理解,用内置类型转换为自定义对象,就相当于构造一个自定义对象。
classA{public:A(int a):a1(a),a2(a){}private:int a1;int a2;};
在这里插入图片描述

而当构造函数前加上关键字explicit,可以使这个构造函数不支持隐式类型转换。这就是之前我们学习智能指针时构造函数加了它的原因,我们不希望一个普通指针悄悄转换为智能指针。不过,还是支持强制类型转换的

在这里插入图片描述

2. 自定义类型转为内置类型

一个自定义类型对象想要转换为内置类型,需要内部重载operator()。这里不是常规的运算符重载,和仿函数中重载operator()的写法也不一样。它的用法是operator 类型(){...}(也可以加explicit修饰),转换的方式是函数体内自定义的,举个例子:

classA{public:A(int a):a1(a),a2(a){}operatorint(){return a1 + a2;}private:int a1;int a2;};
在这里插入图片描述

智能指针中,关于向bool类型的转换,就是这样写的:

在这里插入图片描述

3. 自定义类型之间的转换

自定义类型之间的转换,也是需要有相关的构造函数,很好理解,不再赘述。

4. 类型安全与C++的四种强制类型转换方式

4.1 什么是类型安全?

类型安全是指,编程语言在编译和运行时提供保护机制,避免非法的类型转换和操作,导致出现内存访问错误等,从而减少程序运行时的错误。

C语言不是类型安全的语言, 因为C语言允许隐式类型转换,一些特殊情况下就会导致越界访问的内存错误。不合理的使用强制类型转换也会导致问题,比如一个int*的指针强转成 double*的话,访问就会出现越界。
C++兼容C语言,也支持隐式类型转换和强制类型转换,它也不是类型安全的语言。因此,C++提出了四个显示强制类型转换 操作符static_cast / reinterpret_cast / const_cast / dynamic_cast,就是为了让类型转换相对而言更安全。

4.2 static_cast

static_cast用于两个意义相近的类型之间的转换,比如整型之间、整型和浮点型之间、普通类型和其引用类型之间等。

double a =1.234;int b =static_cast<int>(a);float c =static_cast<float>(b);int&& d =static_cast<int&&>(b);

4.3 reinterpret_cast

reinterpret_cast用于底层的类型转换,比如将一种类型的指针/引用直接转换为另一种类型。这种类型的转换后,对于内存的访问方式就会改变了,因此使用时需要很谨慎,自己要清楚明白使用后是否会出现问题。

int a =1;int* p1 =&a;char* p2 =reinterpret_cast<char*>(p1);

4.4 const_cast

const_cast用于const对象向非const对象的转换,会去掉const属性,使用时同样需要谨慎。

在这里插入图片描述

4.5 dynamic_cast

dynamic_cast主要用于多态类型之间的转换,尤其是用于基类指针/引用向派生类指针/引用的转换,因为派生类的指针/引用向基类指针/引用的转换是天然支持的(也就是切片)。
但是,它不是简单基类转换为派生类。一个基类的指针/引用,它可能指向的是一个基类的对象,也可能指向的是一个派生类对象的切片。dynamic_cast只能作用在后者,只有这个基类指针/引用指向的是派生类对象的切片,才能完成转换。对于前者情况,就不能转换,如果是基类指针指向基类,转换失败返回nullptr,如果是基类引用指向基类,转换失败抛出bad_cast异常

dynamic_cast还要求基类必须是多态类型,也就是必须有虚函数,因为它的运行时通过虚表中存储的type_info来判断一个基类指针/引用指向的是基类对象还是派生类对象。

classA{public:virtualvoidfunc(){}};classB:publicA{};
在这里插入图片描述

本篇完,感谢阅读

Read more

人工智能:自然语言处理高级应用与前沿发展

人工智能:自然语言处理高级应用与前沿发展

人工智能:自然语言处理高级应用与前沿发展 学习目标 💡 理解自然语言处理(NLP)的前沿技术和发展趋势 💡 掌握高级NLP应用(如文本生成、情感分析、机器翻译) 💡 学会使用前沿NLP模型(如GPT-3、BERT、T5) 💡 理解NLP在多模态融合、零样本学习、少样本学习中的应用 💡 通过实战项目,开发一个高级文本生成应用 重点内容 * NLP前沿技术和发展趋势 * 高级NLP应用(文本生成、情感分析、机器翻译) * 前沿NLP模型(GPT-3、BERT、T5) * 多模态融合、零样本学习、少样本学习 * 实战项目:高级文本生成应用开发 一、NLP前沿技术和发展趋势 1.1 多模态融合 1.1.1 多模态融合的基本概念 多模态融合是将不同模态的数据(如文本、图像、音频)结合起来,进行处理和分析的过程。它可以提高模型的性能和准确性。

By Ne0inhk
2026 国内 AI 编程套餐(Coding Plan)全量横评:选型指南与避坑手册

2026 国内 AI 编程套餐(Coding Plan)全量横评:选型指南与避坑手册

在 2026 年的开发环境下,当养龙虾成为潮流,AI 编程助手已经从“选配”变成了“标配”。为了让开发者能以更低的门槛在 Cursor、Cline、Claude Code 等工具中使用顶级国产大模型,各大厂商纷纷推出了 Coding Plan(订阅套餐)。 面对琳琅满目的选择,本文将从价格、额度机制、模型生态三个维度进行深度拆解,帮你省下不必要的开销。 一、 核心选型:五大平台一句话总结 如果你想快速决策,请参考下表: 平台入门价格(常规)首月特惠(新客)核心亮点推荐人群智谱 GLM¥49/月无客户端支持最广(20+ 款),自带 MCP 工具链(视觉、联网、代码仓库检索)追求极致工具兼容性的职业开发者火山方舟¥40/月¥8.91

By Ne0inhk

Flutter 三方库 dart_format 的鸿蒙化适配指南 - 在鸿蒙系统上构建极致、透明、自定义的项目代码风格治理与工程效能格式化引擎

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 dart_format 的鸿蒙化适配指南 - 在鸿蒙系统上构建极致、透明、自定义的项目代码风格治理与工程效能格式化引擎 在鸿蒙(OpenHarmony)系统的工程化研发、多模块 HAP/HAR 代码风格统一、或者是需要一键执行代码质量检查(Linter)的场景中,如何摆脱固定的 dart format 工具限制,转而使用一个更灵活、更具定制深度、且完全跨平台的代码风格压实工具?dart_format 为开发者提供了一套工业级的、基于 Dart 语法的可配置格式化方案。本文将深入实战其在鸿蒙 CI/CD 效能底座中的应用。 前言 什么是 Dart Format?它不仅是一个简单的缩进调整器,而是一个具备深厚 AST(抽象语法树)解析思想的“

By Ne0inhk

Flutter 三方库 inject_annotation 的鸿蒙化适配指南 - 在鸿蒙系统上构建极致、严谨的编译期依赖注入架构实战

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 inject_annotation 的鸿蒙化适配指南 - 在鸿蒙系统上构建极致、严谨的编译期依赖注入架构实战 在鸿蒙(OpenHarmony)系统开发大型、复杂的企业级应用时,如何优雅地解耦各个业务模块?传统的构造函数注入往往会导致代码冗长且难以维护。inject_annotation 为鸿蒙开发者提供了一套基于编译期生成的、零反射的依赖注入(Dependency Injection)方案。本文将带您深入实战其在鸿蒙生态中的应用。 前言 什么是依赖注入?它是一种控制反转(IoC)的实现方式,旨在将对象的创建与使用分离。与运行时反射注入不同,inject_annotation 借鉴了 Java 端 Dagger 的设计思想,在编译阶段就生成了所有的注入代码。在注重性能和确定性的鸿蒙系统开发中,这种“预编译”的 DI 方案能大幅降低运行期开销,并显著提升代码的健壮性。 一、

By Ne0inhk