当前位置: 首页 > news >正文

C++:类型转换

目录

一、C语言中的类型转换

二、C++四种强制类型转换

static_cast

reinterpret_cast

const_cast

dynamic_cast



C++查找手册icon-default.png?t=N7T8https://legacy.cplusplus.com/

一、C语言中的类型转换

        模糊的讲,所有的类型转换都有一个不成文的约束:只有彼此有一定关联的类型才可以互相转换。

        C语言中的类型转换分为:

  • 隐式类型转换
  • 强制类型转换(显式类型转换)

        发生隐式类型转换的情况:

1.整型家族之间(int、short、char)
int i = 10;
char c = i;//编译通过,隐式类型转换
2.整型和浮点数之间
int i = 10;
double d = i;//编译通过、隐式类型转换
3.bool类型和整型
if(0)
while(1)
4.bool类型和指针
while(ptr)

        需要强制类型转换的情况

1.指针和整型
int i = 10;
int* p = &i;int a = (int)p;//如果不强制类型转换,编译会报错
2.不同类型的指针之间
int i = 10;
int* p = &i;char c = 'a';
char* pc = &c;p = (int*)pc;//如果不强制类型转换,编译会报错

        而C++使用面向对象的思想,C++中的类型分为内置类型自定义类型,内置类型的互相转换规则同C语言一样,因此,C++的类型转换更多的讨论是关于内置类型自定义类型之间。

        自定义类型和内置类型之间的转换是通过构造函数支持的。

1.内置类型转换为自定义类型,由相应的构造函数实现,属于隐式类型转换
string s = "abcd";//本质是string支持const char* 的构造函数const string& ss = "abcd";//引用要使用const,因为类型转换中间都会产生具有常性的临时变量
2.自定义类型转换为自定义类型,也是由构造函数支持
3.自定义类型转换为内置类型,需要特殊的重载函数,比如自定义类型A要转换为int
class A
{
public:operator int(){return _a1 + _a2;}
private:int _a1 = 1;int _a2 = 2;
};

        以上的类型转换规则,由于继承C的风格,有一些缺陷:转换的可视性差难以跟踪错误的转换。

        因此C++在保证兼容C风格的类型转换前提下,引入了四种命名形式的类型转换操作符

二、C++四种强制类型转换

static_cast

        static_cast用于非多态类型的转换(静态转换),编译器隐式执行的任何类型转换都可以用static_cast,但它不能用于两个不相关的类型进行转换。

int main()
{double d = 12.34;int a = static_cast<int>(d);cout << a << endl;return 0;
}

reinterpret_cast

        reinterpret_cast用来规范原来的强制类型转换。

int main()
{double d = 12.34;int a = static_cast<int>(d);cout << a << endl;// 这里使用static_cast会报错,应该使用reinterpret_cast//将int转换为指针int* p = reinterpret_cast<int*>(a);return 0;
}

const_cast

        const_cast一般用来去掉变量的const属性。

void Test()
{const int a = 2;int* p = const_cast<int*>(&a);//注意<>的类型一般为指针或引用*p = 3;cout << a << endl;
}

        运行结果

        可见我们的要求并没有实现(不是)。其实在内存中变量a的值已经修改为了3,但是由于寄存器中还存储着原来的值(因为是常量,并不会轻易修改),所以去掉const属性是会造成内存可视优化风险的,因此新增关键字volatile来解决。

void Test()
{volatile const int a = 2;int* p = const_cast<int*>(&a);*p = 3;cout << a << endl;
}


dynamic_cast

        dynamic_cast,在继承体系中,一般用于将父类对象的指针或引用动态的转换子类对象的指针或引用(向下转换)。

        在继承体系中,有两种转换的说法。

  • 向上类型转换

        向上转换是指子类对象“转换”为父类对象,本质不是类型转换,而是赋值兼容规则。

class A
{
public:int _a = 0;virtual void f() {}//该继承体系须支持多态
};class B : public A
{
public:int _b = 1;
};int main()
{//向上类型转换,其实不是类型转换,而是赋值兼容规则,子类向上“转换”为父类B bb;A aa = bb;A* ptr = &bb;return 0;
}
  • 向下转换

        向下转换是指父类对象“转换”为子类对象

void fun(A* pa);//A是父类

        根据继承中的语法规则

        如果pa原来指向子类,此时向下转换是安全的。

        如果pa原来指向父类,此时向下转换为子类,会造成越界访问,是不安全的。

        而dynamic_cast就是用来动态转换父子类。

void fun(A* pa)
{// 向下转换:父->子// pa指向子类对象,转回子类,是安全的// pa指向父类对象,转回子类,是不安全的,存在越界的风险问题// 传统写法,不安全//B* pb = (B*)pa;//  pa指向子类对象,转回子类,正常转换//  pa指向父类对象,转回子类,转换失败B* pb = dynamic_cast<B*>(pa);if (pb){cout << pb << endl;cout << pb->_a << endl;cout << pb->_b << endl;}else{cout << "转换失败" << endl;}
}

RTTI(Run-time Type identification)运行时类型识别

        C++通过以下方式实现RTTI:

  • typeid运算符
  • dynamic_cast运算符
  • decltype 

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Linux之多线程概念
  • 深度学习5从0到1理解RNN(包括LTSM,GRU等):内容丰富(下)
  • Ubuntu22.04版本左右,开机自动启动脚本
  • 7个流行的开源数据治理工具
  • 「图::存储」链式邻接表|链式前向星(C++)
  • Python世界:输入输出之回文串判别实践
  • 如何使用python抓包,附代码
  • java中prepareStatement怎么用
  • SpringBoot2:学SpringBoot前的知识准备-用IDEA创建传统的webapp工程,并整合SpringMVC
  • qt配合halcon深度学习网络环境配置
  • SQLite Insert 语句
  • 反射: 获取变量类型
  • 【例003】利用MATLAB绘制有趣平面图形
  • 基于多种机器学习的房价预测研究【数据抓取、预处理、可视化、预测】
  • 【鸿蒙蓝牙连接】
  • 深入了解以太坊
  • 时间复杂度分析经典问题——最大子序列和
  • 【从零开始安装kubernetes-1.7.3】2.flannel、docker以及Harbor的配置以及作用
  • 2017-09-12 前端日报
  • Android Volley源码解析
  • Android系统模拟器绘制实现概述
  • CentOS学习笔记 - 12. Nginx搭建Centos7.5远程repo
  • ECMAScript6(0):ES6简明参考手册
  • js如何打印object对象
  • Python语法速览与机器学习开发环境搭建
  • spring学习第二天
  • tensorflow学习笔记3——MNIST应用篇
  • underscore源码剖析之整体架构
  • vue2.0项目引入element-ui
  • 编写符合Python风格的对象
  • 从0搭建SpringBoot的HelloWorld -- Java版本
  • 从0实现一个tiny react(三)生命周期
  • 个人博客开发系列:评论功能之GitHub账号OAuth授权
  • 给自己的博客网站加上酷炫的初音未来音乐游戏?
  • 经典排序算法及其 Java 实现
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 推荐一款sublime text 3 支持JSX和es201x 代码格式化的插件
  • 我从编程教室毕业
  • 移动端唤起键盘时取消position:fixed定位
  • 树莓派用上kodexplorer也能玩成私有网盘
  • ​ 全球云科技基础设施:亚马逊云科技的海外服务器网络如何演进
  • ​ArcGIS Pro 如何批量删除字段
  • ‌分布式计算技术与复杂算法优化:‌现代数据处理的基石
  • # 20155222 2016-2017-2 《Java程序设计》第5周学习总结
  • #define,static,const,三种常量的区别
  • #Lua:Lua调用C++生成的DLL库
  • #QT(TCP网络编程-服务端)
  • #鸿蒙生态创新中心#揭幕仪式在深圳湾科技生态园举行
  • (1)Hilt的基本概念和使用
  • (2020)Java后端开发----(面试题和笔试题)
  • (2024)docker-compose实战 (8)部署LAMP项目(最终版)
  • (30)数组元素和与数字和的绝对差
  • (arch)linux 转换文件编码格式
  • (c语言版)滑动窗口 给定一个字符串,只包含字母和数字,按要求找出字符串中的最长(连续)子串的长度
  • (ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY)讲解