C++中的算术转换、其他隐式类型转换和显示转换详解
C++中的类型转换(Type Conversion)是指将一个数据类型的值转换为另一个数据类型的过程,主要包括:
一、算术类型转换(Arithmetic Conversions)
算术类型转换通常发生在算术运算或比较中,称为**“标准转换”(standard conversion),遵循一定的提升规则(promotion rules)**。
转换规则(简化版):
bool→int- 整型提升:
char、short→int - 两个操作数不同类型时:
- 若一个为浮点型,另一个为整型 → 整型转换为浮点型
- 若一个为
double,另一个为float→float转为double - 若一个为
unsigned且它的值不能用int表示 →int转为unsigned - 否则,
unsigned提升优先级高于signed
示例:
#include <iostream>
int main() {char c = 100;int i = 200;float f = 1.5f;double d = 3.14;auto result1 = c + i; // char → int,结果是 intauto result2 = i + f; // int → float,结果是 floatauto result3 = f + d; // float → double,结果是 doublestd::cout << "result1: " << result1 << "\n"; // 300std::cout << "result2: " << result2 << "\n"; // 201.5std::cout << "result3: " << result3 << "\n"; // 4.64
}
二、其他隐式类型转换(Implicit Conversion)
这是 编译器自动完成 的转换,也叫类型提升(promotion)或类型协同(coercion)。
常见的隐式转换:
| 类型 | 转换方向 | 示例 |
|---|---|---|
| 数值型 | 更大/更精度的数值 | int → double |
| 指针类型 | 派生类 → 基类 | Derived* → Base* |
| 空指针 | nullptr → 任何指针类型 | nullptr → int* |
| 数组/函数 → 指针 | int arr[] → int* |
示例:
void printDouble(double d) {std::cout << "Double: " << d << "\n";
}class Base {};
class Derived : public Base {};int main() {int i = 42;printDouble(i); // int → double(隐式)Derived d;Base* bptr = &d; // Derived* → Base*(隐式)
}
三、显示类型转换(Explicit Conversion / Cast)
你可以显式地指示编译器进行类型转换,有四种标准C++风格的转换方式(推荐),以及一个C风格的转换(不推荐)。
四种C++显式转换:
-
static_cast<T>(expr)
➤ 用于基本类型之间转换、指针/引用向上转换等安全转换。 -
dynamic_cast<T>(expr)
➤ 用于带有虚函数的多态类之间的安全运行时类型检查和向下转换。 -
const_cast<T>(expr)
➤ 添加或去除const、volatile限定符,常用于函数参数处理。 -
reinterpret_cast<T>(expr)
➤ 不安全但允许的位级别转换,如指针与整数之间转换。 -
(T)expr—— C风格强制转换
➤ 组合了上述所有功能,不安全不透明,不推荐使用。
示例:
#include <iostream>
class Base { public: virtual ~Base() {} };
class Derived : public Base { public: void say() { std::cout << "Derived\n"; } };int main() {int i = 100;double d = static_cast<double>(i); // int → doubleBase* b = new Derived();Derived* dptr = dynamic_cast<Derived*>(b); // 安全向下转型if (dptr) dptr->say();const int ci = 42;int* p = const_cast<int*>(&ci); // 去除 const 限定void* vptr = reinterpret_cast<void*>(p); // int* → void*int* iptr = reinterpret_cast<int*>(vptr); // void* → int*delete b;
}
四、总结对比表:
| 转换类型 | 触发方式 | 安全性 | 用途/说明 |
|---|---|---|---|
| 算术转换 | 自动 | 安全 | 数值运算中的标准提升 |
| 隐式转换 | 自动 | 通常安全 | 函数调用/指针/基本类型提升 |
static_cast | 显式 | 安全 | 编译期可检查的转换,如 int→float,向上转型 |
dynamic_cast | 显式 | 安全 | 多态类型的运行时向下转型 |
const_cast | 显式 | 有风险 | 去除 const/volatile |
reinterpret_cast | 显式 | 不安全 | 位级别转换,极端情况用 |
| C风格强制转换 | 显式 | 不推荐 | 混合多个C++转换,缺乏类型安全 |
五、综合例子
下面是一个C++ 示例工程,通过一个模拟图形系统的类结构,演示了**各种类型转换(隐式、算术、显示转换)**的组合使用。代码里有注释,方便理解每一种转换在什么时候触发、为什么安全或者不安全。
定义 shape.h图形类头文件内容如下:
#pragma once
#include <iostream>
#include <string>class Shape {
public:virtual ~Shape() {}virtual void draw() const;
};class Circle : public Shape {
public:Circle(double r);void draw() const override;double getRadius() const;
private:double radius;
};class Rectangle : public Shape {
public:Rectangle(int w, int h);void draw() const override;int area() const;
private:int width, height;
};// 模拟图形渲染系统的底层资源对象
struct RenderHandle {void* data;
};RenderHandle createHandle(int id);
shape.cpp 图形类实现如下:
#include "shape.h"void Shape::draw() const {std::cout << "Drawing Shape\n";
}Circle::Circle(double r) : radius(r) {}
void Circle::draw() const {std::cout << "Drawing Circle with radius: " << radius << "\n";
}
double Circle::getRadius() const {return radius;
}Rectangle::Rectangle(int w, int h) : width(w), height(h) {}
void Rectangle::draw() const {std::cout << "Drawing Rectangle of area: " << area() << "\n";
}
int Rectangle::area() const {return width * height;
}RenderHandle createHandle(int id) {RenderHandle h;h.data = reinterpret_cast<void*>(id); // 显式 reinterpret_castreturn h;
}
main.cpp 主函数演示各种类型转换示例内容如下:
#include "shape.h"
#include <typeinfo>void printDouble(double d) {std::cout << "Double value: " << d << "\n";
}int main() {// 算术类型转换(int → double)int i = 42;double d = i; // 隐式转换printDouble(d); // 参数是 doublefloat f = static_cast<float>(i); // 显式 static_caststd::cout << "Float from int: " << f << "\n";// 基类 → 派生类的动态转换(dynamic_cast)Shape* s = new Circle(3.5);s->draw();if (Circle* c = dynamic_cast<Circle*>(s)) {std::cout << "Radius from casted circle: " << c->getRadius() << "\n";}// const_cast 演示const int ci = 100;int* modifiable = const_cast<int*>(&ci);*modifiable = 999; // 未定义行为,仅演示用std::cout << "Modified const int (unsafe!): " << *modifiable << "\n";// reinterpret_cast 演示int resourceID = 1234;RenderHandle h = createHandle(resourceID);int recoveredID = reinterpret_cast<int>(h.data);std::cout << "Recovered ID from RenderHandle: " << recoveredID << "\n";// 隐式派生 → 基类(安全)Rectangle rect(10, 20);Shape* s2 = ▭s2->draw(); // 虚函数,多态行为delete s;return 0;
}
示例的演示内容如下:
| 场景 | 类型转换 | 涉及关键字/方式 |
|---|---|---|
int → double | 算术隐式转换 | 自动 |
float ← int | 算术显式转换 | static_cast |
Base* ← Derived* | 隐式向上转换 | 自动 |
Derived* ← Base* | 安全运行时转换 | dynamic_cast |
const int* ← int* | 添加/去除 const | const_cast |
void* ←→ int | 指针/整数转换 | reinterpret_cast |
Shape 多态行为 | 虚函数机制 | 隐式 |
相关文章:
C++中的算术转换、其他隐式类型转换和显示转换详解
C中的类型转换(Type Conversion)是指将一个数据类型的值转换为另一个数据类型的过程,主要包括: 一、算术类型转换(Arithmetic Conversions) 算术类型转换通常发生在算术运算或比较中,称为**“标…...
GAIA-2:用于自动驾驶的可控多视图生成世界模型
25年3月来自英国创业公司 Wayze 的论文“GAIA-2: A Controllable Multi-View Generative World Model for Autonomous Driving”。(注:23年9月其发布GAIA-1) 生成模型为模拟复杂环境提供一种可扩展且灵活的范例,但目前的方法不足…...
(一)CMake / MsBuild Ninja Make/ MSVC g++ clang++ 等c++编译概念解释
c 几个编译概念 一 概念二 层级关系总结2.1层级表格2.2 关键点说明2.3 示例流程(以 Ninja 为例)2.4 示例流程(Windows 平台) 三 总结 一 概念 CMake 通过 CMakeLists.txt 生成不同平台的构建文件(如 .sln、build.n…...
创建 Node.js Playwright 项目:从零开始搭建自动化测试环境
一、环境准备 在开始创建 Playwright 项目之前,确保你的电脑上已经安装了以下工具: Node.js:Playwright 依赖于 Node.js 环境,确保你已经安装了最新版本的 Node.js。可以通过以下命令检查是否安装成功: node -v npm -…...
浅谈AI致幻
文章目录 当前形势下存在的AI幻觉(AI致幻)什么是AI幻觉AI幻觉的类型为什么AI会产生幻觉AI幻觉的危害与影响当前应对AI幻觉的技术与方法行业与学术界的最新进展未来挑战与展望结论 当前形势下存在的AI幻觉(AI致幻) 什么是AI幻觉 …...
postman乘法计算,变量赋值
postman脚本怎么计算乘法 在Postman中,你可以通过多种方式计算乘法,这取决于你的具体需求。例如,如果你想在发送请求前计算乘法结果,或者在测试标签中计算响应数据的乘法,下面是一些常见的方法。 1. 使用JavaScript代…...
自定义错误码的必要性
为什么要使用错误码,直接返回一个错误信息不好么? 下面介绍一下,在程序开发中使用错误码的必要性~ 便于排查问题 想象你开了一家奶茶店,顾客下单后可能出现各种问题: 没珍珠了(错误码:50…...
车载软件架构 --- 二级boot设计说明需求规范
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 周末洗了一个澡,换了一身衣服,出了门却不知道去哪儿,不知道去找谁,漫无目的走着,大概这就是成年人最深的孤独吧! 旧人不知我近况,新人不知我过…...
管理杂谈——采石矶大捷的传奇与启示
南宋抗金史上,岳飞与岳家军的铁血传奇家喻户晓,但另一位力挽狂澜的“文官战神”却常被忽视——他从未掌兵,却在南宋存亡之际整合溃军,以少胜多,缔造采石矶大捷。此人正是虞允文。一介书生何以扭转乾坤?他的…...
Java高效合并Excel报表实战:GcExcel让数据处理更简单
前言:为什么需要自动化合并Excel? 在日常办公场景中,Excel报表合并是数据分析的基础操作。根据2023年企业办公效率报告显示: 财务人员平均每周花费6.2小时在Excel合并操作上人工合并的错误率高达15%90%的中大型企业已采用自动化…...
第十四届蓝桥杯 2023 C/C++组 平方差
目录 题目: 题目描述: 题目链接: 思路: 核心思路: 第一种思路: 第二种思路: 坑点: 代码: 数学找规律 O(n) 50分代码详解: O(1)满分代码详解&#x…...
前端路由缓存实现
vue3缓存实现完整版,查看这篇设计和实现方式吧,更完整...
I/O复用函数的使用——select
I/O复用函数的使用——select 目录 一、概念 二、select接口 2.1 基础概念 2.2 使用 select 函数的标准输入读取代码 2.3 基于 select 模型的多客户端 TCP 服务器实现 一、概念 i/o复用使得程序能同时监听多个文件描述符,可以提高程序性能。 之前为了让服务器能…...
ubuntu20.04安装安装x11vnc服务基于gdm3或lightdm这两种主流的显示管理器。
前言:在服务端安装vnc服务,可以方便的远程操作服务器,而不用非要插上显示器才行。所以在服务器上安装vnc是很重要的。在ubuntu20中,默认的显示管理器已经变为gdm3,它可以带来与 GNOME 无缝衔接的体验,强调功…...
图像预处理-图像轮廓特征查找
其实就是外接轮廓,有了轮廓点就可以找到最上、最下、最左、最右的四个坐标(因为有xmin,xmax,ymin,ymax)。就可以绘制出矩形。 一.外接矩形 cv.boundingRect(轮廓点) - 返回x,y,w,h,传入一个轮廓的轮廓点,若有多个轮廓需…...
全同态加密医疗数据分析集python实现
目录 摘要一、前言二、全同态加密与医疗数据分析概述2.1 全同态加密(FHE)简介2.2 医疗数据分析需求三、数据生成与预处理四、系统架构与流程4.1 系统架构图五、核心数学公式六、异步任务调度与(可选)GPU 加速七、PyQt6 GUI 设计八、完整代码实现九、自查测试与总结十、展望…...
list的学习
list的介绍 list文档的介绍 list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一…...
HarmonyOS:Navigation实现导航之页面设置和路由操作
导读 设置标题栏模式设置菜单栏设置工具栏路由操作页面跳转页面返回页面替换页面删除移动页面参数获取路由拦截 子页面页面显示类型页面生命周期页面监听和查询 页面转场关闭转场自定义转场共享元素转场 跨包动态路由系统路由表自定义路由表 示例代码 Navigation组件适用于模块…...
管道位移自动化监测方案
一、背景 管道系统在区域性地质沉降作用下易形成非均匀应力场集中现象,诱发管体屈曲变形及环焊缝界面剥离等连续损伤累积效应,进而导致管道力学性能退化与临界承载能力衰减。传统人工巡检受限于空间覆盖度不足及数据采集周期长(≥72h…...
AI之pdf解析:Tesseract、PaddleOCR、RapidPaddle(可能为 RapidOCR)和 plumberpdf 的对比分析及使用建议
目录标题 Tesseract、PaddleOCR、RapidPaddle(可能为 RapidOCR)和 plumberpdf 的对比分析1. Tesseract类型: 开源 OCR 引擎特点:缺点:适用场景: 2. PaddleOCR (推荐)类型:特点:缺点:适用场景: 复杂版式文档、多语言混合文本、需要高精度识别的场景&#…...
【学习笔记】机器学习(Machine Learning) | 第五周| 分类与逻辑回归
机器学习(Machine Learning) 简要声明 基于吴恩达教授(Andrew Ng)课程视频 BiliBili课程资源 文章目录 机器学习(Machine Learning)简要声明 一、逻辑回归的基本原理分类判断条件模型输出的解释Sigmoid 函数与 Logistic 函数逻辑…...
悬停以及点击切换图片
为了实现悬停切换图片的功能,我们可以为每个按钮添加鼠标悬停事件监听器。以下是详细步骤和代码: 首先在控制器类中添加初始化方法,并添加事件监听器: package com.example.demo6;import javafx.event.ActionEvent; import java…...
Python 深度学习 第8章 计算机视觉中的深度学习 - 卷积神经网络使用实例
Python 深度学习 第8章 计算机视觉中的深度学习 - 卷积神经网络使用实例 内容概要 第8章深入探讨了计算机视觉中的深度学习,特别是卷积神经网络(convnets)的应用。本章详细介绍了卷积层和池化层的工作原理、数据增强技术、预训练模型的特征…...
Python基础总结(九)之推导式
文章目录 一、列表推导式1.1 列表推导式的格式1.2 列表推导式的注意事项1.3 列表推导式示例 二、 字典推导式2.1 字典推导式格式2.2 字典推导式注意事项2.3 字典推导式示例 三、 元组推导式3.1 元组推导式格式3.3 元组推导式示例 Python中的推导式有列表推导式,字典…...
[免费]SpringBoot+Vue博物馆(预约)管理系统【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的SpringBootVue博物馆(预约)管理系统,分享下哈。 项目视频演示 【免费】SpringBootVue博物馆(预约)管理系统 Java毕业设计_哔哩哔哩_bilibili 项目介绍 随着计算机科学技术的日渐成熟ÿ…...
基于LangChain4J的AI Services实践:用声明式接口重构LLM应用开发
基于LangChain4J的AI Services实践:用声明式接口重构LLM应用开发 前言:当Java开发遇上LLM编程困境 在LLM应用开发领域,Java开发者常面临两大痛点:一是需要手动编排Prompt工程、记忆管理和结果解析等底层组件,二是复杂…...
制作一款打飞机游戏12:初稿原型
当前进展 任务回顾:在之前,我们做了大量的规划和原型设计。我们创建了关卡,添加了侧向滚动和BOSS模式背景重复,还制作了一个紧凑的瓦片集。原型完成:我们完成了五个原型,基本实现了飞机飞行、滚动…...
【python】pyCharm常用快捷键使用-(2)
pyCharm常用快捷键使用 快速导入任意类 【CTRLALTSPACE】代码补全【CTRLSHIFTENTER】代码快速修正【ALTENTER】代码调试快捷键...
位运算,状态压缩dp(算法竞赛进阶指南学习笔记)
目录 移位运算一些位运算的操作最短 Hamilton 路径(状态压缩dp模板,位运算) 0x是十六进制常数的开头;本身是声明进制,后面是对应具体的数; 数组初始化最大值时用0x3f赋值; 移位运算 左移 把二…...
极狐GitLab 项目 API 的速率限制如何设置?
极狐GitLab 是 GitLab 在中国的发行版,关于中文参考文档和资料有: 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 项目 API 的速率限制 (BASIC SELF) 引入于 15.10 版本,功能标志为rate_limit_for_unauthenticated_projects_api_…...
