C++显性契约与隐性规则:类型转换

C++显性契约与隐性规则:类型转换

文章目录

关于类型转换,通常是隐式转换或者强制转换,C++ 提供了一些能够显式表示转换的运算符,能够更好的规避一些风险和错误

1.传统的类型转换

C 语言中,如果赋值运算符左右两侧类型不同,或者形参与实参类型不匹配,或者返回值类型与接收返回值类型不一致时,就需要发生类型转化

voidTest(){int i =1;// 隐式类型转换double d = i;printf("%d, %.2f\n", i, d);int* p =&i;// 显示的强制类型转换int address =(int)p;printf("%x, %d\n", p, address);}

转换分为显式和隐式:

  1. 隐式类型转化:编译器在编译阶段自动进行,能转就转,不能转就编译失败
  2. 显式类型转化:需要用户自己处理

然而这两种转换的前提是逻辑相近:

  • 基本类型间的转换(如 intdouble
  • 继承层级中的转换(如子类→父类、父类→子类)
  • 用户定义的转换(如 operator T() 或带参数的构造函数)
string s; vector<int>=(vector<int>) s;

这种转换就会失败,因为逻辑不相近

对于强制转换还有一种特殊易错的场景

intmain(){constint n =10;int* p =(int*)&n;(*p)++; string s; vector<int>=(vector<int>) s; cout << n << endl; cout <<*p << endl;return0;}

无论是有点 C 语言基础的人,甚至是学完 C++ 的初学者,都很容易认为这里的输出结果是:n11*p11。但是结果并非所愿,输出结果:n10*p11

实际上这里涉及到存储规则的问题,因为 nconst 变量,那么会被识别为一个常变量,可能会是一个经常被使用的值,就把 n 存入寄存器,把频繁使用的变量的值暂存到寄存器中,这样在后续对该变量的读取操作中,就不需要每次都去内存中读取,直接从寄存器中获取即可,因为寄存器的读写速度比内存快很多

通常 cout 输出的值都是在内存里读取的,相比寄存器,内存读写速度较慢,但内存容量相对寄存器大很多,大多的代码都是存在这里的

因此这里输出的 n 是取自内存器,*p 取自内存

volatileconstint n =10;

volatile 关键字表示该变量的值可能会在程序未明确指定的情况下被改变,编译器不会对其进行优化,即不会被存入寄存器,这样取到的 n 就是内存中及时更新的值

C 风格的转换格式很简单,但是有不少缺点的:

  1. 隐式类型转化有些情况下可能会出问题:比如数据精度丢失
  2. 显式类型转换将所有情况混合在一起,代码不够清晰

因此 C++ 提出了自己的类型转化风格,注意因为 C++ 要兼容 C 语言,所以 C++ 中还可以使用 C 语言的转化风格

2.C++强制类型转换

2.1 static_cast

intmain(){double d =12.34;int a =static_cast<int>(d); cout << a << endl;return0;}

static_cast 需要逻辑上的相近性

2.2 reinterpret_cast

intmain(){// 这里使用static_cast会报错,应该使用reinterpret_cast//int *p = static_cast<int*>(a);int* p =reinterpret_cast<int*>(a);return0;}

reinterpret_cast 几乎无类型限制,不要求类型相近,可强制转换任意指针或整数类型,但极其危险,可能导致:

  • 违反别名规则(如通过 char* 修改 int
  • 函数指针转换后调用,引发崩溃
  • 平台依赖(如不同架构的指针大小不同)

2.3 const_cast

voidTest(){volatileconstint a =2;int* p =const_cast<int*>(&a);*p =3; cout << a << endl;}

仅改变类型的 const / volatile 属性,这里用 reinterpret_cast 也不行的,因为 const 的转换是有风险的

2.4 dynamic_cast

classA{public:virtualvoidf(){}};classB:publicA{};voidfun(A* pa){// dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回 B* pb1 =static_cast<B*>(pa); B* pb2 =dynamic_cast<B*>(pa); cout <<"pb1:"<< pb1 << endl; cout <<"pb2:"<< pb2 << endl;}intmain(){ A a; B b;fun(&a);fun(&b);return0;}

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

  • 向上转型: 子类对象指针/引用->父类指针/引用(不需要转换,赋值兼容规则)
  • 向下转型: 父类对象指针/引用->子类指针/引用(用 dynamic_cast 转型是安全的)

pa 是指向子类对象 B 的,转换可以成功,正常返回地址;pa 是指向父类对象 A 的,转换失败,返回空指针

🔥值得注意的是: 必须是继承关系中的类,基类必须包含虚函数

3.RTTI

RTTI:Run-time Type identification 的简称,即:运行时类型识别

C++ 通过以下方式来支持 RTTI

  1. typeid 运算符
  2. dynamic_cast 运算符
  3. decltype

希望读者们多多三连支持

小编会继续更新

你们的鼓励就是我前进的动力!

请添加图片描述

Read more

Java 大视界 -- Java+Flink CDC 构建实时数据同步系统:从 MySQL 到 Hive 全增量同步(443)

Java 大视界 -- Java+Flink CDC 构建实时数据同步系统:从 MySQL 到 Hive 全增量同步(443)

Java 大视界 -- Java+Flink CDC 构建实时数据同步系统:从 MySQL 到 Hive 全增量同步(443) * 引言: * 正文: * 一、 核心认知:Flink CDC 与全增量同步逻辑 * 1.1 Flink CDC 核心原理 * 1.1.1 与传统数据同步方案的对比(实战选型参考) * 1.2 全增量同步核心逻辑(MySQL→Hive) * 1.2.1 关键技术点(实战必关注,每个点都踩过坑) * 二、 环境准备:生产级环境配置(可直接复用) * 2.1 核心依赖配置(pom.xml)

By Ne0inhk
Redis Java 集成到 Spring Boot

Redis Java 集成到 Spring Boot

Hi~!这里是奋斗的明志,很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~~ 🌱🌱个人主页:奋斗的明志 🌱🌱所属专栏:Redis 📚本系列文章为个人学习笔记,在这里撰写成文一为巩固知识,二为展示我的学习过程及理解。文笔、排版拙劣,望见谅。 Redis Java 集成到 Spring Boot * 一、使用 Spring Boot 连接 Redis 单机 * 1.创建Spring Boot 项目 * 2.勾选相关依赖(Dependencies) * 3.界面显示 * 二、配置 Redis 服务地址 * 1.在 application.yml 中配置 * 2.映射端口号 * 三、创建 Controller

By Ne0inhk
(最新原创毕设)Java上门帮厨管理系统/03.01白嫖源码+演示录像)|可做计算机毕设Java、Python、PHP、小程序APP、C#、爬虫大数据、单片机、文案

(最新原创毕设)Java上门帮厨管理系统/03.01白嫖源码+演示录像)|可做计算机毕设Java、Python、PHP、小程序APP、C#、爬虫大数据、单片机、文案

摘  要 随着现代生活节奏的加快和人们对便捷、高质量餐饮服务需求的增加,上门帮厨作为一种新兴的服务模式逐渐受到欢迎。然而,传统的上门帮厨管理方式依赖于电话预约和手工记录,不仅效率低下,而且难以满足用户对服务质量透明度和个性化的需求。为此,本文提出了一个基于Spring Boot框架的临沂上门帮厨管理系统。该系统旨在通过信息化手段优化厨师与用户之间的互动流程,提高服务效率,增强用户体验,并为管理者提供有效的运营支持。 基于Spring Boot的临沂上门帮厨管理系统集成了多种功能模块,以满足不同用户群体的需求。普通用户可以通过注册登录进入系统,浏览首页展示的轮播图、菜品资讯、菜品信息推荐等信息,并进行相关操作。系统提供了菜品资讯的查看、点赞、收藏和评论功能,以及菜品信息的详情查看、评分、预约等功能。用户还可以在线提交问题反馈,查看个人账户信息并进行修改。 厨师用户可以查看订单详情,进行订单审核和回复,提交佣金提现申请,并查看提现记录。这些功能模块的设计充分考虑了厨师的实际需求,旨在帮助他们更好地管理和提升自己的服务水平。 管理员负责整个系统的运维工作,包括新注册用户的审核、菜品信

By Ne0inhk

【AI测试全栈:质量】39、Training-Serving Skew终结者:Python+Java+Vue三端联动的特征工程全链路测试实战指南

Training-Serving Skew终结者:Python+Java+Vue三端联动的特征工程全链路测试实战指南(附完整代码) 摘要 在AI生产环境中,90%的模型效果衰减并非源于算法本身,而是特征工程环节的Training-Serving Skew(训练-服务偏差)所致。 本文深度解析特征工程的三大核心测试目标(一致性、稳定性、有效性),通过Python(数据处理)、Java(分布式计算)、Vue(可视化监控)三端协同,构建企业级特征工程测试体系。涵盖电商推荐与金融风控双场景实战,提供可直接落地的完整代码实现与踩坑优化方案。 一、Training-Serving Skew:模型失效的隐形杀手 1.1 问题定义与影响 Training-Serving Skew指训练阶段与服务阶段特征数据在计算逻辑、数据格式、时间窗口、数据延迟等环节产生的系统性差异。这种偏差如同"数据寄生虫",悄然吞噬模型效果: * 案例:某视频推荐模型离线NDCG@10达0.137,上线后3周内用户

By Ne0inhk