cpp基础学习笔记03:类型转换

news2024/11/15 15:56:46

static_cast 静态转换

  • 用于类层次结构中基类和派生类之间指针或者引用的转换。up-casting (把派生类的指针或引用转换成基类的指针或者引用表示)是安全的;down-casting(把基类指针或引用转换成子类的指针或者引用)是不安全的。
  • 用于基本数据类型之间的转换,如把int转换成char,这种转换的安全性也要由开发人员来保证。
  • 可以把空指针转换成目标类型的空指针(null pointer)。
  • 把任何类型的表达式转换成void类型。
  • 注意: static_cast不能转换掉expression的const、volitale或者__unaligned属性。

基本类型转换:

#include <iostream>

int main()
{
    int b = 20;
    float ft = 30.25f;
    
    b = static_cast<float>(ft);
    std::cout << "After static_cast b: " << b << std::endl;

    std::cout << "Finished! \n";
    return 0;
}

类的基本转换:

#include <iostream>

class Base
{
public:
    Base(int data):_data(data){}

    void printData()
    {
        std::cout << "Base data: " << _data << std::endl;
    }

private:
    int _data;
};

class TestA : public Base
{
public:
    TestA(int num, int data): _num(num), Base(data){}

    void printData()
    {
        std::cout << "TestA Num: " << _num << std::endl;
    }

private:
    int _num;
};

int main()
{
    Base base{ 10 };
    TestA testA{ 10,20 };

    // 向上转换
    Base* base_ptr = static_cast<Base*>(&testA);
    base_ptr->printData();

    // 向下转换:危险行为
    TestA* test_ptr = static_cast<TestA*>(&base);
    test_ptr->printData();

    std::cout << "Finished! \n";
    return 0;
}

观察,向上转换正常,向下转换数据未定义。

dynamic_cast

typeid必须是类的指针、类的引用或者void*。如果typeid是类的指针类型,那么expression也必须是指针,如果typeid是一个引用,那么expression也必须是一个引用。一般情况下,dynamic_cast用于具有多态性的类(即有虚函数的类)的类型转换。

dynamic_cast依赖于RTTI信息,其次,在转换时,dynamic_cast会检查转换的source对象是否真的可以转换成target类型,这种检查不是语法上的,而是真实情况的检查。先看RTTI相关部分,通常,许多编译器都是通过vtable找到对象的RTTI信息的,这也就意味着,如果基类没有虚方法,也就无法判断一个基类指针变量所指对象的真实类型,这时候,dynamic_cast只能用来做安全的转换,例如从派生类指针转换成基类指针。而这种转换其实并不需要dynamic_cast参与。也就是说,dynamic_cast是根据RTTI记载的信息来判断类型转换是否合法的。

  • 主要用于类层次之间的up-casting和down-casting,还可以用于类之间的交叉转换。在进行down-casting时,dynamic_cast具有类型检查的功能,比static_cast更安全。检测在运行时进行。如果被转换的指针不是一个被请求的有效完整的对象指针,返回值为NULL。当用于多态类型时,它允许任意的隐式类型转换以及相反过程。不过,与static_cast不同,在后一种情况里(注:即隐式转 换的相反过程),dynamic_cast会检查操作是否有效。也就是说,它会检查转换是否会返回一个被请求的有效的完整对象。

  • 注意:dynamic_cast不能转换掉expression的const、volitale或者__unaligned属性。

测试,加入现在的基类没有定义虚函数:

class Base
{
public:
    Base(int data):_data(data){}

    void printData()
    {
        std::cout << "Base data: " << _data << std::endl;
    }

private:
    int _data;
};

class TestA : public Base
{
public:
    TestA(int num, int data): _num(num), Base(data){}

    void printData()
    {
        std::cout << "TestA Num: " << _num << std::endl;
    }

private:
    int _num;
};

int main()
{
    Base* base_ptr = new Base(10);
    TestA* test_ptr = new TestA(10,20);
    
    Base* ptr_01 = dynamic_cast<Base*>(test_ptr);
    ptr_01->printData();    // ok

#if 0
    TestA* ptr_02 = dynamic_cast<TestA*>(base_ptr); // error
    ptr_02->printData();
#endif

    std::cout << "Finished! \n";
    return 0;
}

重新定义并测试:

class VirtualBase
{
private:
    int _data;

public:
    VirtualBase(int data): _data(data){}
    virtual ~VirtualBase(){}
    virtual void printData()
    {
        std::cout << "Virtual Base. Data: " << _data << std::endl;
    }
};

class TestB : public VirtualBase
{
private:
    int _num;

public:
    TestB(int num, int data): _num(num), VirtualBase(data){}
    ~TestB(){}
    void printData() override
    {
        std::cout << "TestB. Data: " << _num << std::endl;
    }
};

int main()
{
    // 定义
    VirtualBase* virual_base_ptr = new VirtualBase(30);
    TestB* test_b_ptr = new TestB(40, 50);
    
    // 派生类指向父类,ok
    VirtualBase* ptr_03 = dynamic_cast<VirtualBase*>(test_b_ptr);
    ptr_03->printData();        // ok
    
    // 父类指向指向派生类,error
    TestB* ptr_04 = dynamic_cast<TestB*>(virual_base_ptr);
    // ptr_04->printData();    // error
    
    // 转换失败返回了nullptr,所以一般需要额外判断
    if (ptr_04 != nullptr)
        ptr_04->printData();

    std::cout << "Finished! \n";
    return 0;
}

reinterpret_cast

转换一个指针为其他类型的指针,也允许将一个指针转换为整数类型,反之亦然。这个操作符能够在非相关的类型之间进行转换。操作结果只是简单的从一个指针到别的指针的值的二进制拷贝,在类型之间指向的内容不做任何类型的检查和转换。这是一个强制转换。使用时有很大的风险,慎用之。(反正少用就完事儿了)

const_cast

这个类型操纵传递对象的const属性,或者是设置或者是移除(也不常用)

参考资料

C++ | 四种类型转换_c++四种类型转换-CSDN博客

https://www.cnblogs.com/daihanlong/p/5550530.html

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

微服务day02-Ribbon负载均衡与Nacos安装与入门

一.Ribbon负载均衡 在上一节中&#xff0c;我们通过在RestTemplte实例中加上了注解 LoadBalanced,表示将来由RestTemplate发起的请求会被Ribbon拦截和处理&#xff0c;实现了访问服务时的负载均衡&#xff0c;那么他是如何实现的呢&#xff1f; 1.1 Ribbon负载均衡的原理 Rib…

(定时器/计数器)中断系统(详解与使用)

讲解 简介 定时器/计数器 定时器实际上也是计数器,只是计数的是固定周期的脉冲 定时和计数只是触发来源不同(时钟信号和外部脉冲)其他方面是一样的。 定时器在单片机内部就像一个小闹钟一样,根据时钟的输出信号,每隔“一秒”,计数单元的数值就增加一,当计数单元数值…

[pdf]《软件方法》2024版部分公开-共196页

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 潘加宇《软件方法》2024版部分公开pdf文件&#xff0c;共196页&#xff0c;已上传CSDN资源。 也可到以下地址下载&#xff1a; http://www.umlchina.com/url/softmeth2024.html 如果…

韦东山嵌入式Liunx入门驱动开发四

文章目录 一、异常与中断的概念及处理流程1-1 中断的引入1-2 栈(1) CPU实现a ab的过程(2) 进程与线程 1-3 Linux系统对中断处理的演进1-4 Linux 中断系统中的重要数据结构(1) irq_desc 结构体(2) irqaction 结构体(3) irq_data 结构体(4) irq_domain 结构体(5) irq_domain 结构…

T3SF:一款功能全面的桌面端技术练习模拟框架

关于T3SF T3SF是一款功能全面的桌面端技术练习模拟框架&#xff0c;该工具针对基于主场景事件列表的各种事件提供了模块化的架构&#xff0c;并包含了针对每一个练习定义的规则集&#xff0c;以及允许为对应平台参数定义参数的配置文件。 该工具的主模块能够执行与其他特定模…

BetterDisplay Pro for Mac v2.0.11激活版:屏幕显示优化专家

BetterDisplay Pro是一款由waydabber开发的Mac平台上的显示器校准软件&#xff0c;可以帮助用户调整显示器的颜色和亮度&#xff0c;以获得更加真实、清晰和舒适的视觉体验。 软件下载&#xff1a;BetterDisplay Pro for Mac v2.0.11激活版下载 &#x1f50d; 精准校准&#xf…

Python实现DMI工具判断信号:股票技术分析的工具系列(3)

Python实现DMI工具判断信号&#xff1a;股票技术分析的工具系列&#xff08;3&#xff09; 介绍算法解释 代码rolling函数介绍完整代码 介绍 先看看官方介绍&#xff1a; DMI (趋向指标&#xff09; 用法 1.PDI线从下向上突破MDI线&#xff0c;显示有新多头进场&#xff0c;为…

vscode+remote突然无法连接服务器以及ssh连接出问题时的排错方法

文章目录 设备描述状况描述解决方法当ssh连接出问题时的排错方法 设备描述 主机&#xff1a;win11&#xff0c;使用vscode的remote-ssh插件 服务器&#xff1a;阿里云的2C2GUbuntu 22.04 UFIE 状况描述 之前一直使用的是vscode的remote服务&#xff0c;都是能够正常连接服务…

LabVIEW流量控制系统

LabVIEW流量控制系统 为响应水下航行体操纵舵翼环量控制技术的试验研究需求&#xff0c;通过LabVIEW开发了一套小量程流量控制系统。该系统能够满足特定流量控制范围及精度要求&#xff0c;展现了其在实验研究中的经济性、可靠性和实用性&#xff0c;具有良好的推广价值。 项…

在学习云原生的时候,一直会报错ImagePullBackOff Back-off pulling image

在学习云原生的时候&#xff0c;一直会报错 &#xff08;见最后几张图&#xff09; ImagePullBackOff Back-off pulling image 然后我就在像。这个配置的镜像是不是可以自己直接下载&#xff0c;但是好像不怎么搜索得到 然后就在想&#xff0c;这个lfy_k8s_images到底是个啥玩…

TikTok矩阵系统功能怎么写?常用源代码是什么?

TikTok矩阵系统的功能是如何编写的?又有哪些常用的源代码支撑这些功能呢?本文将通过五段源代码的分享&#xff0c;为大家揭开TikTok矩阵系统的神秘面纱。 一、TikTok矩阵系统的核心功能 TikTok的矩阵系统涵盖了多个核心功能&#xff0c;包括但不限于用户管理、内容分发、推…

飞腾平台编译安装openGauss数据库

1. 环境检查 1.1 检查OS版本 openGauss支持的操作系统&#xff1a; CentOS 7.6&#xff08;x86_64 架构&#xff09;openEuler-20.03-LTS&#xff08;aarch64 架构&#xff09;openEuler-20.03-LTS&#xff08;x86_64架构&#xff09;Kylin-V10&#xff08;aarch64 架构&…

mysql-Synch-clickhouse

Synch GitHub - long2ice/synch: Sync data from the other DB to ClickHouse(cluster) 环境&#xff1a; mysql5.7 redis > 5.0 clickhouse21.2 postgresql python3 binlog_formatrow XREAD default pg_config synch 1&#xff1a;安装clickhouse rpm下载地址&…

map和set例题应用

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 目录 第一题 第二题 第三题 第一题 随机链表的复制https://leetcode.cn/problems/copy-list-with-random-pointer/description/ 思路 首先遍历旧链表&#xff0c;并创建新节点&#xff0c;同时用map将旧节点与新节点…

ICASSP2024 | ICMC-ASR 车载多通道语音识别挑战赛总结

为促进驾驶场景中语音处理和识别研究&#xff0c;在ISCSLP 2022上成功举办智能驾驶座舱语音识别挑战 (ICSRC)的基础上&#xff0c;西工大音频语音与语言处理研究组 (ASLPNPU)联合理想汽车、希尔贝壳、WeNet社区、字节、微软、天津大学、南洋理工大学以及中国信息通信研究院等多…

动态规划--(算法竞赛、蓝桥杯)--二维费用背包

1、B站视频链接&#xff1a;E15 背包DP 二维费用背包_哔哩哔哩_bilibili #include <bits/stdc.h> using namespace std; int f[101][101]; //f[j][k]第i件物品&#xff0c;体积<j,重量<k的最大价值int main(){int n,V,W;//物品、容量、承重int v,w,val;//体积、重…

IIS部署.Net 7项目

&#x1f468; 作者简介&#xff1a;大家好&#xff0c;我是Taro&#xff0c;前端领域创作者 ✒️ 个人主页&#xff1a;唐璜Taro &#x1f680; 支持我&#xff1a;点赞&#x1f44d;&#x1f4dd; 评论 ⭐️收藏 文章目录 前言一、发布项目二、解决发布失败1.发布失败2.托管…

【论文笔记】An Effective Adversarial Attack on Person Re-Identification ...

原文标题&#xff08;文章标题处有字数限制&#xff09;&#xff1a; 《An Effective Adversarial Attack on Person Re-Identification in Video Surveillance via Dispersion Reduction》 Abstract 通过减少神经网络内部特征图的分散性攻击reid模型。 erbloo/Dispersion_r…

Scratch 第十四课-打地鼠游戏

第十四课-打地鼠游戏 学习目标 这节课我们一起来做一款打地鼠游戏 如何画圆形以及如何使用复制粘贴功能随机数在游戏中的实际应用逻辑运算符与判断语句的使用 程序设计 程序分析 &#xff1a; 打地鼠游戏小朋友们都玩过&#xff0c;在多个洞里面随机伸出老鼠的头&#xff0…

Github配置ssh key的步骤

1. 检查本地主机是否已经存在ssh key 是否存在 id_rsa 和 id_rsa.pub文件&#xff0c;如果存在&#xff0c;说明已经有SSH Key 如下图所示&#xff0c;则表明已经存在 如果存在&#xff0c;直接跳到第三步 2. 生成ssh key 如果不存在ssh key&#xff0c;使用如下命令生…