【深入理解C++】类型转换

2023-10-31

1.隐式类型转换

系统自动进行,不需要程序开发人员介入。

int n = 3 + 45.6;
cout << n << endl; // 48

double m = 3 + 45.6;
cout << m << endl; // 48.6

2.显式类型转换(强制类型转换)

2.1 C语言

格式:(type)expressiontype(expression)

int n = 5 % (int)3.2;
cout << n << endl; // 2

int m = 5 % int(3.2);
cout << m << endl; // 2

2.2 C++语言

C++ 强制类型转换分为 4 种,这 4 种强制类型转换分别用于不同的目的,每一种都有一个不同的名字,提供了更丰富的含义和功能、更好的类型检查机制,方便代码的书写和维护。

格式:强制类型转换名<type>(expression),其中 type 是要转成的目标类型,expression 是待转换的值。

2.2.1 static_cast

编译的时候就会进行类型转换的检查,代码中要保证转换的安全性与正确性,没有运行时安全检查。

static_cast 可以理解为“正常转换”,其含义跟 C 语言中的强制类型转换差不多。

2.2.1.1 可用于

(1) 相关类型转换,比如整型和实型之间的转换。

double f = 100.98;

int n = (int)f;
cout << n << endl; // 100

int m = static_cast<int>(f);
cout << m << endl; // 100

(2) 子类类型转换为父类类型。

class A {};
class B : public A {};

B b;
A a = static_cast<A>(b);

(3) void * 与其他类型指针之间的转换。

int i = 10;
int* p1 = &i;
void* q = static_cast<void*>(p1);
int* p2 = static_cast<int*>(q);

2.2.1.2 不可用于

(1) 一般不能用于指针类型之间的转换,比如 int *double *float *double * 等。

#include <iostream>

using namespace std;

int main()
{
    double num = 100.0f;
    double* p1 = &num;
    int* p2 = static_cast<int*>(p1); // 不可以
    float* p3 = static_cast<float*>(p1); // 不可以

    return 0;
}

(2) 不能交叉转换,即不是同一继承体系的无法转换。

2.2.2 dynamic_cast

运行时类型识别与检查。

主要用于父类型和子类型之间的转换,即父类型指针指向子类型对象,然后用 dynamic_cast 把父指针类型转换为子指针类型。

2.2.3 const_cast

编译时类型转换。

用于去除指针或者引用的 const 属性。

#include <iostream>

using namespace std;

int main()
{
    const int n = 90;
    const int* p1 = &n;
    int* p2 = const_cast<int*>(p1); // 语法正确
    
    *p2 = 120; // 虽然语法上没问题,但这种赋值行为是一种未定义行为,不建议

    cout << n << endl;
    cout << *p1 << endl;
    cout << *p2 << endl;

    cout << &n << endl;
    cout << p1 << endl;
    cout << p2 << endl;

    return 0;
}

从下图中可以看出,n 仍然保留着原来的值 90,但是它们的确指向了同一个地址,这真是一件奇怪的事情!不过,这是一件好事:说明 C++ 里是 const 就是 const,外界千变万变,我就不变,不然真的就乱套了,const 也就没有存在的意义了。

未定义行为(Undefined Behavior)就是这个语句在标准 C++ 中没有明确的规定,由编译器来决定如何处理。

在这里插入图片描述

2.2.4 reinterpret_cast

编译时类型转换。

reinterpret_cast 运算符用来处理无关类型之间的转换,它会产生一个新的值,这个值与原始参数 expressoin 有完全相同的比特位。

reinterpret 意思是“重新解释”,即将操作数内容解释为另一种不同的类型,属于比较底层的强制转换,没有任何类型检查和格式转换,仅仅是简单的二进制数据拷贝。

  • 可以交叉转换

  • 任意指针或引用类型之间的转换

  • 从指针类型到一个足够大的整数类型

  • 从整数类型或枚举类型到指针类型

#include <iostream>

using namespace std;

int main()
{
    int n = 90;
    int* p1 = &n;
    void* p2 = reinterpret_cast<void*>(p1);
    int* p3 = reinterpret_cast<int*>(p2);

    return 0;
}

reinterpret_cast 可以乱转、自由转,被认为是危险的类型转换,但只要好好用、合乎规则地用,其实 reinterpret_cast 也很好用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【深入理解C++】类型转换 的相关文章

  • WinForms:如何确定窗口是否不再活动(没有子窗口具有焦点)?

    我的应用程序使用多个窗口 我想隐藏一个特定窗口 以防应用程序失去焦点 当活动窗口不是应用程序窗口时 source https stackoverflow com questions 466354 how can i tell if a wi
  • 为什么libc++的shared_ptr实现使用完整内存屏障而不是宽松内存屏障?

    在boost的实现中shared ptr 它用放松内存排序以增加其引用计数 https github com boostorg smart ptr blob master include boost smart ptr detail sp
  • 我的线程图像生成应用程序如何将其数据传输到 GUI?

    Mandelbrot 生成器的缓慢多精度实现 线程化 使用 POSIX 线程 Gtk 图形用户界面 我有点失落了 这是我第一次尝试编写线程程序 我实际上并没有尝试转换它的单线程版本 只是尝试实现基本框架 到目前为止它是如何工作的简要描述 M
  • 为什么大多数 C 开发人员使用 Define 而不是 const? [复制]

    这个问题在这里已经有答案了 在许多程序中 define与常量具有相同的用途 例如 define FIELD WIDTH 10 const int fieldWidth 10 我通常认为第一种形式优于另一种形式 它依赖于预处理器来处理基本上是
  • 如何创建可以像 UserControl 一样编辑的 TabPage 子类?

    我想创建一个包含一些控件的 TabPage 子类 并且我想通过设计器来控制这些控件的布局和属性 但是 如果我在设计器中打开子类 我将无法像在 UserControl 上那样定位它们 我不想创建一个带有 UserControl 实例的 Tab
  • 使用post方法将多个参数发送到asp.net core 3 mvc操作

    使用 http post 方法向 asp net mvc core 3 操作发送具有多个参数的 ajax 请求时存在问题 参数不绑定 在 dot net 框架 asp net web api 中存在类似的限制 但在 asp net mvc
  • C++:重写已弃用的虚拟方法时出现弃用警告

    我有一个纯虚拟类 它有一个纯虚拟方法 应该是const 但不幸的是不是 该接口位于库中 并且该类由单独项目中的其他几个类继承 我正在尝试使用这个方法const不会破坏兼容性 至少在一段时间内 但我找不到在非常量方法重载时产生警告的方法 以下
  • C# 中的接口继承

    我试图解决我在编写应用程序时遇到的相当大的 对我来说 问题 请看这个 为了简单起见 我将尝试缩短代码 我有一个名为的根接口IRepository
  • Clang 编译器 (x86):80 位长双精度

    我正在尝试在 x86 Windows 平台上使用本机 80 位长双精度 海湾合作委员会选项 mlong double 80 https gcc gnu org onlinedocs gcc x86 Options html似乎不适用于 cl
  • 从多个类访问串行端口

    我正在尝试使用串行端口在 arduino 和 C 程序之间进行通信 我对 C 编程有点陌生 该程序有多种用户控制形式 每一个都需要访问串口来发送数据 我需要做的就是从每个类的主窗体中写入串行端口 我了解如何设置和写入串行端口 这是我的 Fo
  • 访问者和模板化虚拟方法

    在一个典型的实现中Visitor模式 该类必须考虑基类的所有变体 后代 在许多情况下 访问者中的相同方法内容应用于不同的方法 在这种情况下 模板化的虚拟方法是理想的选择 但目前这是不允许的 那么 模板化方法可以用来解析父类的虚方法吗 鉴于
  • 如何从网站下载 .EXE 文件?

    我正在编写一个应用程序 需要从网站下载 exe 文件 我正在使用 Visual Studio Express 2008 我正在使用以下代码 private void button1 Click object sender EventArgs
  • 如何在c#中的内部类中访问外部类的变量[重复]

    这个问题在这里已经有答案了 我有两个类 我需要声明两个类共有的变量 如果是嵌套类 我需要访问内部类中的外部类变量 请给我一个更好的方法来在 C 中做到这一点 示例代码 Class A int a Class B Need to access
  • 在 C 中使用 GNU automake 中的解析器

    我是 GNU autotools 的新手 在我的项目中使用了 lex 和 yacc 解析器 将它们作为 makefile am 中的源代码会产生以下错误 配置 in AC CHECK PROGS YACC bison yacc none i
  • 获取 2 个数据集 c# 中的差异

    我正在编写一个简短的算法 它必须比较两个数据集 以便可以进一步处理两者之间的差异 我尝试通过合并这两个数据集并将结果更改放入新的数据集来实现此目标 我的方法如下所示 private DataSet ComputateDiff DataSet
  • 如何一步步遍历目录树?

    我发现了很多关于遍历目录树的示例 但我需要一些不同的东西 我需要一个带有某种方法的类 每次调用都会从目录返回一个文件 并逐渐遍历目录树 请问我该怎么做 我正在使用函数 FindFirstFile FindNextFile 和 FindClo
  • 将代码拆分为标头/源文件

    我从 Asio 的示例页面中获取了以下代码 class tcp connection public boost enable shared from this
  • 双精度类型二维多维数组的 pinvoke 编组作为 c# 和 c++ 之间的输入和输出

    我有以下我正在尝试解决的双物质类型的 2d 多维数组的 c 和 c pinvoke 编组 我已经查看了以下热门内容以获得我目前拥有的内容使用双精度数组进行 P Invoke 在 C 和 C 之间编组数据 https stackoverflo
  • 带重定向标准流的 C# + telnet 进程立即退出

    我正在尝试用 C 做一个 脚本化 telnet 项目 有点类似于Tcl期望 http expect nist gov 我需要为其启动 telnet 进程并重定向 和处理 其 stdin stdout 流 问题是 生成的 telnet 进程在
  • 使用 Crypto++ 获取 ECDSA 签名

    我必须使用 Crypto 在变量中获取 ECDSA 签名 我在启动 SignMessage 后尝试获取它 但签名为空 我怎样才能得到它 你看过 Crypto wiki 吗 上面有很多东西椭圆曲线数字签名算法 http www cryptop

随机推荐

  • RTP/RTCP协议解析

    RTP协议 实时传输协议RTP Real time Transport Protocol 是一个网络传输协议 它是由IETF的多媒体传输工作小组1996年在RFC 1889中公布的 后在RFC3550中进行更新 国际电信联盟ITU T也发布
  • python爬取12306实现按车次查询余票

    前言 本篇博客想写很久了 以前抢票时不知道你们有没有这种情况 比如你想买郑州到长春k926这个车次的票 但是车票买完了抢不到票 于是我就想多买几站看没有票 其实也贵不了多少 也就是说我想多买几站买这个车次郑州 gt 哈尔滨的票 然后到长春下
  • stm32 LWIP开发-1-LWIP 无操作系统移植

    1 网卡基础概念 1 开发板需要实现网络功能的话 需要两个条件 1 硬件 外置网络芯片或者MCU有网络功能 比如 stm32F1 DM9000 MAC PHY stm32F4 内置MAC层 PHY层芯片 2 支持TCP IP协议栈 2 st
  • 数字孪生技术与万亿市场规模的智慧城市

    数字孪生技术与万亿市场规模的智慧城市 近日 由工信部牵头编写的2020年 数字孪生应用白皮书 正式发布 重点介绍了数字孪生技术在智慧制造 智慧城市 智慧交通 智慧能源 智慧建筑 智慧健康6个领域的应用和发展 数字孪生技术在环保领域的应用 通
  • stm32设置延时函数

    查看网上设置延时函数的方法不外乎三种 统一总结一下 第一种 通过设置循环设置延时函数 通过时钟周期 机器周期 指令周期 来具体计算单片机执行一条指令的时间 来进行延时 这种延时不太精确 详细可以看看这篇文章https blog csdn n
  • Virtualbox虚拟机网络配置详解

    目录 1 使用桥接 Bridged Adapter 模式 2 使用HostOnly模式 网络共享的方式 3 使用双网卡 HostOnly模式 NAT转换 在默认情况下 Virtualbox虚拟机选择的上网方式是 网络地址转换 NAT 这种方
  • 浅谈数据结构与算法

    1 什么是数据结构 答 存储 组织数据的方式 数据的种类有很多 字符串 整数 浮点 组织各种数据的方式 即数据元素之间的关系 列表 字典 元组 举例 列表方式 老王 18 男 字典方式 name 老王 age 18 sex 男 综合方式 n
  • Java异常知识点总结

    文章目录 前言 一 异常的基本概念 二 异常的分类 1 异常的层次结构 2 异常的分类 3 try catch和finally 4 getMessage 和 printStackTrace 5 受控异常 6 finally关键字 7 如何声
  • 如何快速将网站封装一个win桌面端应用?怎么将网页打包windows桌面应用?使用Electron将网页打包成win桌面应用

    安装必要的软件 首先需要安装Node js和Electron 您可以访问以下网站下载并安装它们 Node js https nodejs org en Electron https www electronjs org 创建您的应用程序 在
  • idea快速打开java项目_IntelliJ IDEA快速上手(教你如何创建第一个Java项目)

    本篇博客教你如何快速上手使用IntelliJ IDEA 包括一些基础常规配置和Java项目的创建 设置IDEA默认打开方式 设置IDEA不要默认启动最后打开的项目 在项目中或者启动首页 选择settings gt Appearance Be
  • 在C++中引用Fortran Lapack矩阵工具

    http blog sina com cn s blog 8019dfa70100uwaw html 在C 中引用Fortran Lapack矩阵工具 2011 10 22 11 45 07 转载 标签 杂谈 分类 杂代码 前几天接了一个活
  • 扁平数据结构转Tree型数据

    看到这样一个题目 将以下数据按要求输出 let arr id 1 name 部门1 pid 0 id 2 name 部门2 pid 1 id 3 name 部门3 pid 1 id 4 name 部门4 pid 3 id 5 name 部门
  • C语言—单链表的创建与插入操作

    作者 KUST CZY 文章目录 前言 一 创建链表 二 实现核心功能 总结 前言 创建单链表L1 将单链表L1拆成二个链表 其中以L1为头的链表保持原来向后的链接 一个链表的头为L2 其链接方向与L1相反 L1包含原链表的奇数序号的结点
  • SpringBoot的控制反转(IOC)和依赖注入(DI)

    控制反转 IOC IOC Inversion of Control 它是一种设计思想 指的是将原本在程序中由我们手动创建对象的控制权 交给Spring框架来管理 将对象之间的相互依赖关系交给 IoC 容器来管理 并由 IoC 容器完成对象的
  • AltiumDesigner19(AD19)使用设置技巧

    之前用AD16 用的很爽 后来老师说 AD19有在线库的功能 可以减少自己画库了 想想挺合适 就安装了AD19 后来发现AD19用着是各种不爽 首先他卡 只怪我电脑配置跟不上 其次 他的预设值跟AD16相比 都没有进行设置 很多都需自己重新
  • 性能测试相关(TPS/RT/PV等)

    对于我们开发来说 我们日常最熟悉的工作就是把客户的需求实现并交付 但是 事情并不是往往就这样结束了 我们还需要后续对上线的系统进行跟踪调查 查看系统的运行情况 为什么呢 一方面 我们需要关注系统在运行过程中的健康问题 是否有异常等等 另一方
  • svn diff

    svn怎么查看某文件的修改记录 svn diff 文件名 svn diff 文件名 会查看本地版本库中所作的修改 cd 到文件所属的目录下使用 svn diff 文件名 svn diff xx cs 或者直接 svn diff 文件路径 文
  • ChatGPT技术原理

    目录 一 Tokenization 二 Transformer模型 三 预训练 四 微调 五 Beam search 总结 自从OpenAI的ChatGPT在2022年底横空出世以来 这款大型语言模型在各种任务中都展现了惊人的性能 包括问答
  • Acunetix无法正常启动

    Acunetix打开提示无法 按Windows R 打开 services msc打开服务界面 查看Acunetix服务是否开启 如果有服务未启动 右键 启动 重新打开Acunetix登录即可
  • 【深入理解C++】类型转换

    文章目录 1 隐式类型转换 2 显式类型转换 强制类型转换 2 1 C语言 2 2 C 语言 2 2 1 static cast 2 2 1 1 可用于 2 2 1 2 不可用于 2 2 2 dynamic cast 2 2 3 const