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指向A
    A *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指向A
    A *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指向B
        A *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:强制类型转换

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

代码随想录算法训练营第59天 | 583.两个字符串的删除操作 + 72.编辑距离 + 编辑距离总结篇

今日任务 583. 两个字符串的删除操作 72. 编辑距离 编辑距离总结篇 583.两个字符串的删除操作 - Medium 题目链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 给定两个单词 word1 和 word2 &#xff0c;返回使得 word1 和 word2 相同所需的最小步数。 每步 可以…

秒懂百科,C++如此简单丨专栏导读及学习方法

目录 写在前面 专栏独有亮点 专栏目录总览 口头禅 订阅方式 保证 写在结尾 写在前面 本专栏为C的入门课程&#xff0c;包括了C的基础知识和算法入门。 如果你真心想学C&#xff0c;那么你一定要订阅此专栏&#xff0c;里面的21节课能够让新手快速入门。 &#x1f3c5;跟…

全能代码生成器,自动生成前后端代码、生成项目框架、生成JavaBean、生成数据库文档、自动化部署项目(TableGo v8.4.0)

TableGo_20240224 v8.4.0 正式版发布&#xff0c;此次版本累计更新如下&#xff1a; 1、TableGo专属LOGO上线 2、生成数据库文档ER图新增备注字段名的生成配置 3、生成自定义文件功能新增临时参数配置&#xff0c;用于使用临时数据生成自定义文件 4、新增基于Excel数据生成…

【前端素材】推荐优质后台管理系统Vuesy平台模板(附源码)

一、需求分析 后台管理系统在多个层次上提供了丰富的功能和细致的管理手段&#xff0c;帮助管理员轻松管理和控制系统的各个方面。其灵活性和可扩展性使得后台管理系统成为各种网站、应用程序和系统不可或缺的管理工具。下面详细分析后台管理系统的定义和功能&#xff1a; 1.…

一个小老板的日常管理

昨天在“Daily Briefing”公众号的一文《Daily Briefing下一步怎么办&#xff1f;》&#xff0c;收到很多英语爱好者的留言和祝福。 其实“Daily Briefing”也相当于创业前的一次MVP&#xff0c;失败也好&#xff0c;成功也罢&#xff0c;都是自己不错的一段经历。 咱们“知识大…

力扣 48. 旋转图像

1.题目 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]]…

unity学习(41)——创建(create)角色脚本(panel)——UserHandler(收)+CreateClick(发)——发包!

1.客户端的程序结构被我精简过&#xff0c;现在去MessageManager.cs中增加一个UserHandler函数&#xff0c;根据收到的包做对应的GameInfo赋值。 2.在Model文件夹下新增一个协议文件UserProtocol&#xff0c;内容很简单。 using System;public class UserProtocol {public co…

K8s环境搭建

一、基础环境准备 VMware虚拟机&#xff0c;安装三台CentOS&#xff0c;网络环境选择NAT模式&#xff0c;推荐配置如下&#xff08;具体安装步骤省略&#xff0c;网上很多虚拟机安装CentOS7的教程&#xff09; 二、网络环境说明 使用NAT模式&#xff0c;我的IP分别是&#xf…

openGauss学习笔记-227 openGauss性能调优-系统调优-其他因素对LLVM性能的影响

文章目录 openGauss学习笔记-227 openGauss性能调优-系统调优-其他因素对LLVM性能的影响 openGauss学习笔记-227 openGauss性能调优-系统调优-其他因素对LLVM性能的影响 LLVM优化效果不仅依赖于数据库内部具体的实现&#xff0c;还与当前所选择的硬件环境等有关。 表达式调用C…

代码随想录算法训练营第五十七天|647. 回文子串、516.最长回文子序列、动态规划总结篇

题目&#xff1a;647. 回文子串 文章链接&#xff1a;代码随想录 视频链接&#xff1a;LeetCode:647.回文子串 题目链接&#xff1a;力扣题目链接 图释&#xff1a; class Solution { public:int countSubstrings(string s) {// dp[i][j]数组表述&#xff0c;区间范围[i,j]…

Promise相关理解记录

一、Promise基础定义相关 Promise是一个构造函数&#xff0c;调用时需要使用new关键字 Promise是解决回调地狱的一种异步解决方式 Promise有三个状态&#xff1a;pending(进行中)、fulfilled(成功)、rejected(失败) Promise的状态只会从 pending→fulfilled 或者 pending→…

高考志愿选择辅助系统

高考志愿选择辅助系统 获取源码——》公主号&#xff1a;计算机专业毕设大全

Unity中URP实现水体效果(泡沫)

文章目录 前言一、给水上色1、我们在属性面板定义两个颜色2、在常量缓冲区申明这两个颜色3、在片元着色器中&#xff0c;使用深度图对这两个颜色进行线性插值&#xff0c;实现渐变的效果 二、实现泡沫效果1、采样 泡沫使用的噪波纹理2、控制噪波效果强弱3、定义_FoamRange来控制…

基于django的购物商城系统

摘要 本文介绍了基于Django框架开发的购物商城系统。随着电子商务的兴起&#xff0c;购物商城系统成为了许多企业和个人创业者的首选。Django作为一个高效、稳定且易于扩展的Python web框架&#xff0c;为开发者提供了便捷的开发环境和丰富的功能模块&#xff0c;使得开发购物商…

Bluesky数据采集框架-1

Bluesky是一个用于实验控制和科学数据和元数据采集的库。它强调以下特点&#xff1a; 1、实时&#xff0c;流式数据&#xff1a;可用于嵌入可视化和处理。 2、丰富元数据&#xff1a;获取和组织来方便复制性和可检索性。 3、实验通用性&#xff1a;对完全不同的硬件无缝地重…

板块二 JSP和JSTL:第四节 EL表达式 来自【汤米尼克的JAVAEE全套教程专栏】

板块二 JSP和JSTL&#xff1a;第四节 EL表达式 一、什么是表达式语言二、表达式取值&#xff08;1&#xff09;访问JSP四大作用域&#xff08;2&#xff09;访问List和Map&#xff08;3&#xff09;访问JavaBean 三、 EL的各种运算符&#xff08;1&#xff09;.和[ ]运算符&…

Apache Commons开源的工具库介绍

Apache Commons 是 Apache 软件基金会主持的一个项目&#xff0c;旨在提供一系列可重用的 Java 组件。这些组件覆盖了从数据封装、文本处理到网络通信等各个方面&#xff0c;是 Java 开发中常用的一系列工具库。Apache Commons 项目下的各个库通常以 "commons-" 开头…

【README 小技巧】在项目README.md 中展示发布到maven 仓库版本

在项目README.md 中展示发不到nexus 的快照版本 <p align"center"><a target"_blank" href"https://search.maven.org/search?qwu-lazy-cloud-network%20wu-lazy-cloud-network"><img src"https://img-home.csdnimg.cn/ima…

什么是IP地址,IP地址详解

在互联网的世界中&#xff0c;每一台连接的设备都需要一个独特的标识&#xff0c;这就是IP地址。IP地址&#xff0c;全称为“Internet Protocol Address”&#xff0c;即互联网协议地址&#xff0c;它是网络中进行数据传输的基础。下面&#xff0c;我们将对IP地址进行详细的解析…

大公司跨域文件交换,如何兼顾安全效率和经济性?

现如今&#xff0c;随着我国经济的不断发展向前&#xff0c;许许多多的企业其规模也在不断的壮大&#xff0c;大型企业在全国、甚至全球范围的重要地区都设有自己的分支机构&#xff0c;总部与分支机构间&#xff0c;各分支机构间均存在数据交换需求&#xff0c;同时&#xff0…