【c++】四种类型转换形式

【c++】四种类型转换形式

编译时:
static_cast(静态转换)
const_cast(去常性转换)
reinterpret_cast(重新解释转换,直接转换地址)
运行时:
dynamic_cast(动态转换,运行时类型识别 RTTI)


static_cast(静态转换)

用途描述注意事项
基本数据类型之间的转换用于 intdoublecharint 等类型之间的转换。适用于已知类型的转换,比 C 风格转换更安全。
void* 转换为其他类型用于将 void* 指针还原为具体类型的指针。必须确保指针类型正确,避免未定义行为。
左值转换为右值用于将左值转换为右值引用,常用于移动语义。强制转换为右值引用,触发移动构造。
类型层次结构中的指针和引用转换在类继承关系中,用于基类和派生类之间的转换。只能进行安全的向上转换,向下转换需要 dynamic_cast
int 类型转换为枚举允许 int 与枚举类型之间的转换。适用于整数到枚举的安全转换。
static_cast 在模板中的应用用于确保目标类型和原始类型一致,并在模板编程中进行类型转换。使用 static_assert 进行编译期类型检查。

1. 基本数据类型转换

static_cast 可用于基本数据类型之间的转换,如 intdoublecharint,等价于 C 风格转换,但更安全。

#include <iostream>int main() {double d = 3.14159;int i = static_cast<int>(d);  // 截断小数部分,转换为 3char c = 'A';int ascii = static_cast<int>(c);  // 将字符 'A' 转换为 ASCII 码std::cout << "i = " << i << ", ascii = " << ascii << std::endl;return 0;
}

优点:比 C 风格转换更安全,可读性更好,避免了 reinterpret_cast 的风险。


2. void* 转换为其他类型

static_cast 可以用于void* 还原为具体类型,但必须确保指针类型正确,否则可能导致未定义行为。

#include <iostream>int main() {int a = 42;void* pVoid = &a;  // int* → void*int* pInt = static_cast<int*>(pVoid);  // void* → int*std::cout << "pInt = " << *pInt << std::endl;return 0;
}

适用于已知原始类型的情况,如果不确定类型,应使用 reinterpret_cast


3. 左值转换为右值

在 C++11 及更高版本中,static_cast 可以将左值转换为右值引用,用于移动语义

#include <iostream>
#include <utility>  // std::moveclass Data {
public:Data() { std::cout << "构造函数\n"; }Data(const Data&) { std::cout << "拷贝构造\n"; }Data(Data&&) { std::cout << "移动构造\n"; }
};int main() {Data d;Data d2 = static_cast<Data&&>(d);  // 强制转换为右值引用,触发移动构造return 0;
}

std::move 类似,但 static_cast<Data&&> 是显式的转换方式


4. 类型层次结构中的指针和引用转换

类的继承关系中,static_cast 可以在基类和派生类之间进行转换,但仅限安全的向上转换

#include <iostream>class Base {
public:virtual void show() { std::cout << "Base 类\n"; }
};class Derived : public Base {
public:void show() override { std::cout << "Derived 类\n"; }
};int main() {Derived d;Base* pBase = static_cast<Base*>(&d);  // 向上转换pBase->show();  // 仍然调用 Derived 的 `show()`return 0;
}

⚠️ 向下转换(Base*Derived*)是不安全的,需要用 dynamic_cast


5. int 类型转换为枚举

static_cast 允许整数和枚举类型之间的转换

#include <iostream>enum Color { RED, GREEN, BLUE };int main() {int num = 1;Color c = static_cast<Color>(num);  // 将 int 转换为枚举类型std::cout << "c = " << c << std::endl;return 0;
}

适用于整数到枚举的安全转换


6. static_cast 在模板中的应用

在模板编程中,可以使用 static_cast 确保目标类型和原始类型一致

#include <iostream>
#include <type_traits>template <typename T, typename U>
T convert(U value) {static_assert(std::is_convertible<U, T>::value, "类型不兼容!");return static_cast<T>(value);
}int main() {double d = 3.14;int i = convert<int>(d);  // double → intstd::cout << "i = " << i << std::endl;return 0;
}

static_assert 可用于编译期检查类型是否可以转换


const_cast(去常性转换)

特点描述
只能对同类型使用const_cast 类型必须相同。
不能用于基本数据类型不能用于基本数据类型之间的转换(例如:int → double)。
转换目标为指针或引用只能将指针或引用的常量属性去除,而不能作用于值类型。

常量指针/引用被转换为非常量的指针/引用,并仍然指向原来的对象

例子:

  1. 常量指针转为非常量指针

    #include <iostream>void modifyValue(const int* ptr) {// const_cast 去常性转换int* modifiablePtr = const_cast<int*>(ptr);*modifiablePtr = 20;  // 可以修改原对象
    }int main() {const int a = 10;modifyValue(&a);  // 将常量指针转换为非常量指针return 0;
    }
    
  2. 常量引用转为非常量引用

    #include <iostream>void modifyValue(const int& ref) {// const_cast 去常性转换int& modifiableRef = const_cast<int&>(ref);modifiableRef = 20;  // 可以修改原对象
    }int main() {const int a = 10;modifyValue(a);  // 将常量引用转换为非常量引用return 0;
    }
    

注意事项:

  • const_cast 只会移除常量属性,并不会改变对象本身。
  • 对于常量对象的修改仍然是未定义行为,因此不应使用 const_cast 去修改那些原本是常量的数据。

reinterpret_cast(重新解释转换)

是 C++ 中最危险的类型转换之一,它将数据从一种类型“强制”转换为另一种类型,并且不进行任何类型检查。
它是按解释的

特点描述
最危险的转换reinterpret_cast 不进行任何类型检查,可能导致未定义行为。
按位解释转换直接基于内存的二进制表示,不考虑类型的语义。
指针之间的转换可用于不同类型的指针之间的转换。
指针与整数之间的转换可将指针转换为整数,反之亦然。

1. 指针类型转换

#include <iostream>int main() {int a = 42;// 强制将 int* 转换为 double*,危险操作,按位解释double* p = reinterpret_cast<double*>(&a);std::cout << *p << std::endl;  // 不确定行为,可能崩溃return 0;
}

2. 指针与整数转换

#include <iostream>int main() {int* p = reinterpret_cast<int*>(0x1234);  // 将整数转换为指针std::cout << "Pointer: " << p << std::endl;uintptr_t addr = reinterpret_cast<uintptr_t>(p);  // 将指针转换为整数std::cout << "Address as integer: " << addr << std::endl;return 0;
}

动态转换(dynamic_cast

是一种用于在类层次结构中进行指针或引用类型转换的操作,特别适用于下行转换(基类指针或引用转换为派生类指针或引用)。dynamic_cast运行时检查类型安全,依赖于虚函数表和运行时类型信息(RTTI),通过虚函数表中的信息来实现类型检查。

动态转换的基本概念

  1. 上行转换(向上转换)

    • 向上转换是指派生类对象转换为基类指针或引用是在编译时进行的,与静态类型转换等价,不查虚表
  2. 下行转换(向下转换)

    • 向下转换是指基类指针或引用转换为派生类指针或引用。这种转换在运行时需要类型检查
    • 并且只有在公有继承和继承关系中存在虚函数时才有效,否则没有运行时类型信息(RTTI)进行类型检查。
    • 使用 dynamic_cast 来进行下行转换时,转换成功时返回派生类指针或引用,转换失败时返回 nullptr(对于指针类型),或者抛出 std::bad_cast 异常(对于引用类型)。
    • 例如
      class Base {
      public:virtual ~Base() {}  // 必须有虚析构函数,以支持RTTI
      };class Derived : public Base {};int main() {Base* pBase = new Derived();Derived* pDerived = dynamic_cast<Derived*>(pBase);  // 成功,转换为派生类指针if (pDerived) {std::cout << "转换成功!" << std::endl;} else {std::cout << "转换失败!" << std::endl;}delete pBase;return 0;
      }
      
      • 如果 pBase 实际上指向一个 Derived 类型对象,则 pDerived 会成功转换,并指向该对象。
      • 如果 pBase 并不指向 Derived 类型对象,dynamic_cast 将返回 nullptr,指示转换失败。

如何判断是否能够进行下行转换

  • 条件:只有当类之间存在虚函数(如虚析构函数)时,RTTI 才会被启用,dynamic_cast 才能进行类型检查。
  • 执行流程
    1. dynamic_cast 会查询对象的虚函数表(vtable)。
    2. 如果查询到类型匹配,则转换成功。
    3. 如果查询失败,则返回 nullptr(对于指针类型),或抛出异常 std::bad_cast(对于引用类型)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/895268.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Cisco ASR1002查看资源占用的几条命令

查看平台资源 show platform resource 该命令用于显示整个平台的资源使用情况&#xff0c;包括 CPU、内存等 example: ASR1002# show platform resources **State Acronym: H - Healthy, W - Warning, C - Critical Resource…

Day 1:认知革命与DeepSeek生态定位

目标&#xff1a;建立对大模型技术范式的系统性认知&#xff0c;掌握DeepSeek的核心技术特性与生态价值 一、大模型技术演进&#xff1a;从GPT到DeepSeek 1.1 技术发展里程碑 2017-Transformer突破&#xff1a;Self-Attention机制如何突破RNN的序列建模瓶颈 2018-GPT初代&…

Python自动化办公之Excel拆分

在日常办公中&#xff0c;我们经常需要将包含多个Sheet页的Excel文件拆分成多个独立的Excel文件。例如&#xff0c;在发送Excel表给各部门确认时&#xff0c;出于控制知悉范围最小等保密性考虑&#xff0c;每个部门只需要查看和确认自己部门对应的Sheet页。手动拆分Excel文件非…

【CXX-Qt】1.1 Rust中的QObjects

本文涉及到了使用CXX-Qt将Rust、C和QML集成到Qt应用程序中的各个方面。下面&#xff0c;我将提供一个简单的示例&#xff0c;演示如何使用CXX-Qt来创建一个Rust结构体并将其作为QObject子类暴露给C和QML。 一、设置CXX-Qt环境 首先&#xff0c;确保您已经安装了Rust、CXX和CX…

Conda命令整理

Conda 是一个功能强大的包和环境管理工具&#xff0c;广泛用于 Python 开发中。除了基本的包和环境管理功能外&#xff0c;Conda 还提供了许多高级用法和技巧&#xff0c;帮助用户更高效地管理和维护 Python 环境。 1. 管理 Conda 本身 命令描述示例conda --version查看 Cond…

C++模拟实现AVL树

目录 1.文章概括 2.AVL树概念 3.AVL树的性质 4.AVL树的插入 5.旋转控制 1.左单旋 2. 右单旋 3.左右双旋 4.右左双旋 6.全部代码 1.文章概括 本文适合理解平衡二叉树的读者阅读&#xff0c;因为AVL树是平衡二叉树的一种优化&#xff0c;其大部分实现逻辑与平衡二叉树是…

opc da 服务器数据 转 EtherCAT项目案例

目录 1 案例说明 2 VFBOX网关工作原理 3 应用条件 4 查看OPC DA服务器的相关参数 5 配置网关采集opc da数据 6 启动EtherCAT从站转发采集的数据 7 在服务器上运行仰科OPC DA采集软件 8 案例总结 1 案例说明 在OPC DA服务器上运行OPC DA client软件查看OPC DA服务器的相…

实验9 基于WebGoat平台的SQL注入攻击

实验9 基于WebGoat平台的SQL注入攻击 1.实验目的 熟悉WebGoat平台&#xff0c;在该平台上实现SQL注入攻击。 2.实验内容 &#xff08;1&#xff09;下载webgoat-server-8.2.2.jar。 &#xff08;2&#xff09;搭建java环境。 &#xff08;3&#xff09;运行webgoat。 &#xf…

StochSync:可在任意空间中生成360°全景图和3D网格纹理

StochSync方法可以用于在任意空间中生成图像&#xff0c;尤其是360全景图和3D网格纹理。该方法利用了预训练的图像扩散模型&#xff0c;以实现零-shot生成&#xff0c;消除了对新数据收集和单独训练生成模型的需求。StochSync 结合了 Diffusion Synchronization&#xff08;DS&…

研发管理知识

定义 研发管理是对研发活动进行有效的计划、组织、领导和控制的过程&#xff0c;旨在通过合理配置资源、协调团队工作、监控项目进度和质量等&#xff0c;确保研发项目能够按时、按质、按量完成&#xff0c;实现企业的技术创新和产品升级目标&#xff0c;增强企业的核心竞争力。…

HarmonyOS 5.0应用开发——全局自定义弹出框openCustomDialog

【高心星出品】 文章目录 全局自定义弹出框openCustomDialog案例开发步骤完整代码 全局自定义弹出框openCustomDialog CustomDialog是自定义弹出框&#xff0c;可用于广告、中奖、警告、软件更新等与用户交互响应操作。开发者可以通过CustomDialogController类显示自定义弹出框…

AOS安装及操作演示

文章目录 一、安装node1.1 在 macOS 上管理 Node版本1.1.1 安装 nvm1.1.2 验证 nvm 是否安装成功1.1.3 使用 nvm 安装/切换 Node.js 版本1.1.4 卸载 Node.js 版本 1.2 在 windows 上管理 Node版本1.2.1 安装 nvm-windows1.2.2 安装 Node.js 版本1.2.3 切换 Node.js 版本1.2.4 卸…

DeepSeek模型R1服务器繁忙,怎么解决?

在当今科技飞速发展的时代&#xff0c;人工智能领域不断涌现出令人瞩目的创新成果&#xff0c;其中DeepSeek模型无疑成为了众多关注焦点。它凭借着先进的技术和卓越的性能&#xff0c;在行业内掀起了一股热潮&#xff0c;吸引了无数目光。然而&#xff0c;如同许多前沿技术在发…

AIGC-微头条爆款文案创作智能体完整指令(DeepSeek,豆包,千问,Kimi,GPT)

Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列Scratch编程案例软考全系列Unity3D学习专栏蓝桥系列AIGC(GPT、DeepSeek、豆包、千问、Kimi)👉关于作者 专注于Android/Unity和各种游戏开发技巧,以及各种资…

[LLM面试题] 指示微调(Prompt-tuning)与 Prefix-tuning区别

一、提示调整(Prompt Tuning) Prompt Tuning是一种通过改变输入提示语&#xff08;input prompt&#xff09;以获得更优模型效果的技术。举个例子&#xff0c;如果我们想将一条英语句子翻译成德语&#xff0c;可以采用多种不同的方式向模型提问&#xff0c;如下图所示&#xf…

CSS 性能优化全攻略:提升网站加载速度与流畅度

系列文章目录 01-从零开始学CSS选择器&#xff1a;属性选择器与伪类选择器完全指南 02-避免样式冲突&#xff1a;掌握CSS选择器优先级与层叠规则的终极指南 03-如何精确掌控网页布局&#xff1f;深入解析 CSS 样式与盒模型 04-CSS 布局全面解析&#xff1a;从传统浮动到现代 F…

自主项目面试点总结

1、许苑–OJ判题系统 技术栈&#xff1a;Spring BootSpring Cloud AlibabaRedisMybatisMQDocker 项目地址: https://github.com/xuyuan-upward/xyoj-backend-microservice 1.1、项目介绍: 一个基于微服务的OJ系统&#xff0c;具备能够根据管理员预设的题目用例对用户提交的代…

12.推荐系统的前沿技术

接下来我们将学习推荐系统的前沿技术。推荐系统是一个快速发展的领域&#xff0c;许多新技术和新方法不断涌现&#xff0c;进一步提升了推荐系统的性能和效果。在这一课中&#xff0c;我们将介绍以下内容&#xff1a; 图神经网络&#xff08;GNN&#xff09;在推荐系统中的应用…

【py】python安装教程(Windows系统,python3.13.2版本为例)

1.下载地址 官网&#xff1a;https://www.python.org/ 官网下载地址&#xff1a;https://www.python.org/downloads/ 2.64版本或者32位选择 【Stable Releases】&#xff1a;稳定发布版本&#xff0c;指的是已经测试过的版本&#xff0c;相对稳定。 【Pre-releases】&#…

CEF132 编译指南 MacOS 篇 - depot_tools 安装与配置 (四)

1. 引言 在 CEF132&#xff08;Chromium Embedded Framework&#xff09;的编译过程中&#xff0c;depot_tools 扮演着举足轻重的角色。这套由 Chromium 项目精心打造的脚本和工具集&#xff0c;专门用于获取、管理和更新 Chromium 及其相关项目&#xff08;包括 CEF&#xff…