c++的类型转换方法

一、静态类型转换(static_cast)

静态类型的转换主要用于基本类型之间的转换,比如int类型转换为double类型。但是static_cast也可以支持上下行的转换(存在继承关系之间的转换)

基本类型之间的转换举例

 上下行转换的举例

#include <iostream>
#include<typeinfo>
using namespace std;class A
{
public:int a=1;int b=2;int c=3;};class B:public A
{
public:int d=4;int e=5;int f=6;
};int main()
{//用指针实例化一个类对象A *ptr_a=new A();B *ptr_b=new B();cout<<"A的数据:"<<ptr_a->a<<endl<<"B的数据:"<<ptr_b->d<<endl;//A指向B,B指向AA *ptr_a1=static_cast<A *>(new B());//上行转换(子类强行转换为父类),安全B *ptr_b1=static_cast<B *>(new A());//下行转换(父类强行转换为子类),不安全,容易越界,因为父类只能访问自己的cout<<"A指针访问数据:"<<ptr_a1->c<<endl<<"B指针访问数据:"<<ptr_b1->f<<endl;return 0;
}

从输出结果看,下行转换是支持的(输出了数据),结合源代码可知,26708不是我们想要输出的数据,指针访问越界了(A是基类,只能访问自己的空间,也证明了继承关系不具有双向性,继承关系是单向的)

二、动态类型转换(dynamic_cast)

动态类型的转换主要用来转换存在继承关系的指针或引用类型,相比于静态类型转换(static_cast),动态类型转换会进行类型检查,如果转换不安全会抛出异常错误信息

#include <iostream>
#include<typeinfo>
using namespace std;class A
{
public:int a=1;int b=2;int c=3;};class B:public A
{
public:int d=4;int e=5;int f=6;
};int main()
{//用指针实例化一个类对象A *ptr_a=new A();B *ptr_b=new B();cout<<"A的数据:"<<ptr_a->a<<endl<<"B的数据:"<<ptr_b->d<<endl;//A指向B,B指向AA *ptr_a1=dynamic_cast<A *>(new B());//上行转换(子类强行转换为父类),安全B *ptr_b1=dynamic_cast<B *>(new A());//下行转换(父类强行转换为子类),不安全,容易越界,因为父类只能访问自己的cout<<"A指针访问数据:"<<ptr_a1->c<<endl<<"B指针访问数据:"<<ptr_b1->f<<endl;return 0;
}

这段代码运行之后会报异常信息

D:\study\STL\class_cast\main.cpp:31: error: cannot dynamic_cast '(operator new(12u), (<statement>, ((A*)<anonymous>)))' (of type 'class A*') to type 'class B*' (source type is not polymorphic)
     B *ptr_b1=dynamic_cast<B *>(new A());//下行转换(父类强行转换为子类),不安全,容易越界,因为父类只能访问自己的
                                        ^

说明dynamic_cast只支持上行类型转换(子类转换为父类)。

三、常量类型转换(const_cast)

常量类型转换常用来去除指针或引用的常量性。对于指针或引用,常量转换可以将其修改为非常量。例如:

tips:通过指针b可以修改第三方的值

需要注意的是如果修饰某个变量为常量,则不可更改数据,但是未修饰的变量可以更改数据

#include <iostream>
using namespace std;int main()
{int c=6;const int *a=&c;//const修饰的a为常量属性,a不可被修改int *b=const_cast<int *>(a);//类型转换后可以被修改cout<<*a<<" "<<*b<<" "<<c<<endl;*b=9;cout<<*a<<" "<<*b<<" "<<c<<endl;int num=666;const int *ptr_num=const_cast<const int *>(&num);cout<<*ptr_num<<" "<<num<<endl;num=999;cout<<*ptr_num<<" "<<num<<endl;return 0;
}

输出结果:

四、重新解释转换(reinterpret_cast)

重新解释转换用于将一个指针转换为其他类型的指针,该类型转换危险程度极高,容易造成未定义的行为。

reinterpret_cast支持基本类型指针之间的转换

 也支持上下行类型之间的转换包括不相关的类类型之间的转换

#include <iostream>
using namespace std;
class A
{
public:int a=1;int b=2;int c=3;};class B:public A
{
public:int d=4;int e=5;int f=6;
};class C
{
public:int g=7;int h=8;int i=9;
};int main()
{//用指针实例化一个类对象A *ptr_a=new A();B *ptr_b=new B();C *ptr_c=new C();cout<<"A的数据:"<<ptr_a->a<<endl<<"B的数据:"<<ptr_b->d<<endl<<"C的数据:"<<ptr_c->g<<endl;;//A指向B,B指向A,C指向A,A指向C,B指向C,C指向BA *ptr_a1=reinterpret_cast<A *>(new B());B *ptr_b1=reinterpret_cast<B *>(new A());C *ptr_c1=reinterpret_cast<C *>(new A());A *ptr_a2=reinterpret_cast<A *>(new C());B *ptr_b2=reinterpret_cast<B *>(new C());C *ptr_c2=reinterpret_cast<C *>(new B());cout<<"A指针访问数据:"<<ptr_a1->a<<" "<<ptr_a2->c<<endl<<"B指针访问数据:"<<ptr_b1->f<<" "<<ptr_b2->a<<endl<<"C指针访问的数据:"<<ptr_c1->g<<" "<<ptr_c2->i<<endl;return 0;
}

运行结果:

ps:通过运行结果可知,数据访问乱了!

其他

上下行转换关系图

(父类与子类关系可以理解为基类与派生类关系)

其余类型转换方法

类型转换方法其实远不止四个,比如自动类型转换(系统会自动转换)

规则:占用内存字节数少的类型向占用内存字节数多的类型转换(内存字节数可以用值域替代),目的保证精度不降。

编写程序证明有符号类型自动转换为无符号类型(最终输出结果为无符号类型)

 ps2:强制类型转换

(强制转换的类型)(被转换的表达式)

编写程序自证类型发生了强制转换

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

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

相关文章

《Docker 简易速速上手小册》第8章 Docker 在企业中的应用(2024 最新版)

文章目录 8.1 Docker 在开发环境中的应用8.1.1 重点基础知识8.1.2 重点案例&#xff1a;Python Web 应用开发环境8.1.3 拓展案例 1&#xff1a;Python 数据分析环境8.1.4 拓展案例 2&#xff1a;Python 自动化测试环境 8.2 Docker 在生产环境的实践8.2.1 重点基础知识8.2.2 重点…

174基于matlab的雷达数字信号处理

基于matlab的雷达数字信号处理。该程序具备对雷达目标回波的处理能力&#xff0c;能够从噪声中将目标检测出来&#xff0c;并提取目标的距离、速度、角度信息。有相应的试验文档。程序已调通&#xff0c;可直接运行。 174 雷达数字信号处理 目标检测出来 (xiaohongshu.com)

STM32单片机基本原理与应用(八)

温度传感器实验 实验内容&#xff1a; 单片机通过代码模拟1-Wire总线并对DS18B20进行读写&#xff0c;并在TFTLCD屏幕上显示当前实时温度。 电路原理图&#xff1a; 1-Wire总线 1-Wire总线&#xff1a;即单总线协议&#xff0c;采用单根信号线&#xff0c;既传输时钟&#…

高等数学(无穷小与无穷大)

目录 一、无穷小 二、无穷大 三、无穷小与无穷大的关系 四、无穷小量的阶的比较 一、无穷小 二、无穷大 三、无穷小与无穷大的关系 四、无穷小量的阶的比较

直接写就行!EI顶刊组合:多能源微网/综合能源系统两阶段鲁棒优化配置方法代码!

适用平台&#xff1a;MatlabYalmipCplex 参考文献&#xff1a; 《考虑机组禁止运行区间的含风电鲁棒机组组合》-中国电机工程学报 《微电网两阶段鲁棒优化经济调度方法》-中国电机工程学报 程序提出了微电网中电源容量的两阶段鲁棒优化配置模型&#xff0c;第一阶段主要决策…

Swift Combine 使用 handleEvents 操作符调试管道 从入门到精通二十五

Combine 系列 Swift Combine 从入门到精通一Swift Combine 发布者订阅者操作者 从入门到精通二Swift Combine 管道 从入门到精通三Swift Combine 发布者publisher的生命周期 从入门到精通四Swift Combine 操作符operations和Subjects发布者的生命周期 从入门到精通五Swift Com…

LemonSqueezy

信息收集 # nmap -sn 192.168.1.0/24 -oN live.nmap Starting Nmap 7.94 ( https://nmap.org ) at 2024-02-08 11:22 CST Nmap scan report for 192.168.1.1 Host is up (0.00037s latency). MAC Address: 00:50:56:C0:00:08 (VMware) Nmap scan r…

人工智能聊天机器人如何帮助您实现工作与生活的平衡

如何用AI聊天机器人实现高效工作生活平衡 工作与生活平衡是管理个人和职业生活需求和责任的能力。 在当今快节奏和竞争激烈的世界中&#xff0c;工作与生活平衡被视为一个理想的目标。然而&#xff0c;对于忙碌的专业人士来说&#xff0c;实现工作与生活的平衡可能具有挑战性&a…

LeetCode刷题---LRU缓存

LRU LRU是Least Recently Used的缩写&#xff0c;即最近最少使用&#xff0c;是一种内存管理算法&#xff0c;也可以用作缓存淘汰策略。 这种算法的核心思想是&#xff1a;如果数据最近被访问过&#xff0c;那么将来被访问的几率也更高。 因此&#xff0c;当内存或缓存容量有限…

18个惊艳的可视化大屏(第六辑):地图焦点

本期带来的都是以地图作为视觉焦点的可视化大屏页面。

力扣链表篇

以下刷题思路来自代码随想录以及官方题解 文章目录 203.移除链表元素707.设计链表206.反转链表24.两两交换链表中的节点19.删除链表的倒数第N个节点面试题 02.07. 链表相交142.环形链表II 203.移除链表元素 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链…

pclpy 最小二乘法拟合平面

pclpy 最小二乘法拟合平面 一、算法原理二、代码三、结果1.左边原点云、右边最小二乘法拟合平面后点云投影 四、相关数据 一、算法原理 平面方程的一般表达式为&#xff1a; A x B y C z D 0 ( C ≠ 0 ) Ax By Cz D 0 \quad (C\neq0) AxByCzD0(C0) 即&#xff1a; …