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

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

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 0TestA* ptr_02 = dynamic_cast<TestA*>(base_ptr); // errorptr_02->printData();
#endifstd::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);// 派生类指向父类,okVirtualBase* ptr_03 = dynamic_cast<VirtualBase*>(test_b_ptr);ptr_03->printData();        // ok// 父类指向指向派生类,errorTestB* 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

相关文章:

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

static_cast 静态转换 用于类层次结构中基类和派生类之间指针或者引用的转换。up-casting (把派生类的指针或引用转换成基类的指针或者引用表示)是安全的&#xff1b;down-casting(把基类指针或引用转换成子类的指针或者引用)是不安全的。用于基本数据类型之间的转换&#xff…...

H3C OSPF 外部路由引入实验

H3C OSPF 外部路由引入实验 实验拓扑 实验需求 按照图示配置 IP 地址R1&#xff0c;R2&#xff0c;R3 运行 OSPF 使内网互通&#xff0c;所有接口&#xff08;公网接口除外&#xff09;全部宣告进 Area 0&#xff1b;要求使用环回口作为 Router-id业务网段不允许出现协议报文…...

ARM简介

ARM&#xff1a;ARM是Advanced RISC Machine的缩写&#xff0c;意为高级精简指令集计算机。 英国ARM公司&#xff0c;2016年被软银创始人孙正义斥资320亿美元收购了。现在是软银旗下的芯片设计公司&#xff0c;总部位于英国剑桥&#xff0c;专注于设计芯片&#xff0c;卖芯片生…...

MySQL(基础篇)——事务

一.事务简介 事务是一组操作的集合&#xff0c;他是一个不可分割的单位&#xff0c;事务会把所有的操作作色一个整体一起向系统提交或撤销操作请求&#xff0c;即这些操作要么同时成功&#xff0c;要么同时失败。 默认MySQL的事务是自动提交的&#xff0c;也就是说&#xff0c…...

XGB-15:调参注意事项

参数调优是机器学习中的一门黑艺术&#xff0c;一个模型的最优参数可能取决于许多情境。因此&#xff0c;要为此提供全面的指南是不可能的。 了解偏差-方差权衡Bias-Variance Tradeoff 当能允许模型变得更加复杂&#xff08;例如更深&#xff09;&#xff0c;模型具有更好的拟…...

蓝桥杯_定时器的基本原理与应用

一 什么是定时器 定时器/计数器是一种能够对内部时钟信号或外部输入信号进行计数&#xff0c;当计数值达到设定要求时&#xff0c;向cpu提出中断处理请求&#xff0c;从而实现&#xff0c;定时或者计数功能的外设。 二 51单片机的定时/计数器 单片机外部晶振12MHZ&#xff0c;…...

【跨境电商须知】FP独立站的特点和痛点有哪些?

无论是做独立站&#xff0c;还是做亚马逊&#xff0c;都有各自的难点。自己做独立站若要在跨境行业长足发展&#xff0c;既要知道FP独立站有什么特点&#xff0c;要清楚FP独立站的痛点并一一克服。 一、FP独立站的特点 与依赖第三方平台相比&#xff0c;拥有自己的域名、服务器…...

js 精确计算(解决js四则运算精度缺失问题)

js的小数的运算&#xff0c;可能会得到一个不精确的结果&#xff0c;因为所有的运算都要转换成二进制去计算&#xff0c;然而&#xff0c;二进制无法精确表示1/10。 var a 0.1 0.2; console.log(a); //打印结果&#xff1a;0.30000000000000004因此需要使用以下方法实现精确…...

SpringBoot之统一事务管理配置

SpringBoot之自定义Jackson反序列化日期类型转换配置类 文章目录 SpringBoot之自定义Jackson反序列化日期类型转换配置类1. SpringBoot版本2. 统一事务管理配置类3. 主启动类加入开启事务的注解 统一事务管理配置 1. SpringBoot版本 <parent><groupId>org.springfr…...

荒岛生存:以牙签为核心资源的生存策略与思考

设想一下&#xff0c;当你不幸流落荒岛&#xff0c;随身携带的唯一物品是一盒牙签&#xff0c;面对极端环境与匮乏资源&#xff0c;如何运用这一看似微不足道的工具进行生存&#xff0c;成为了一项严峻的挑战。本文旨在探讨如何最大限度地发挥牙签在荒岛生存中的作用&#xff0…...

云计算 2月26号 (进程管理和常用命令)

一、权限扩展 文件权限管理之&#xff1a; 隐藏权限防止root误删除 文件属性添加与查看 [rootlinux-server ~]# touch file1 file2 file3 1.查看文件属性 [rootlinux-server ~]# lsattr file1 file2 file3 ---------------- file1 ---------------- file2 ---------------- f…...

Pytorch中,dim形象化的确切意义是什么?

在Pytorch中涉及张量的操作都会涉及“dim”的设置&#xff0c;虽然也理解个大差不差&#xff0c;但是偶尔还是有点犯迷糊&#xff0c;究其原因还是没有形象化的理解。 首先&#xff0c;张量的维度排序是有固定顺序的&#xff0c;0&#xff0c;1&#xff0c;2&#xff0c;.....…...

跨域引起的两个接口的session_id不是同一个

来源场景&#xff1a; RequestMapping(“/captcha”)接口设置了SESSION_KEY&#xff0c;也能获取到&#xff0c;但是到了PostMapping(“/login”)接口就是空的&#xff0c;由于跨域导致的两个session_id不是同一个 /*** 系统用户 前端控制器*/ Controller CrossOrigin(origins…...

解释一下前端框架中的虚拟DOM(virtual DOM)和实际DOM(real DOM)之间的关系。

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…...

【MyBatis-Plus】之queryWrapper.apply用法

目录 一、queryWrapper.apply的含义及其用法 二、其他方法 三、注意事项 官网地址&#xff1a;MyBatis-Plus https://baomidou.com/ 一、queryWrapper.apply的含义及其用法 QueryWrapper.apply() 是 MyBatis-Plus 提供的方法&#xff0c;用于构建动态 SQL 查询条件。它允许…...

Centos中安装Docker及Docker的使用

在centos7系统中安装指定版本的docker,并通过docker使用安装mysql为例,阐述docker的使用。 2.1、Docker卸载及安装yum依赖 【卸载Docker,如果安装的Docker的版本不合适】 yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-…...

亿道推出重磅加固平板!为行业发展注入新动力

随着科技生产力的不断发展&#xff0c;各行各业都得到质的飞跃。产品的迭代速度也大大加快&#xff0c;作为全球领先的加固行移动终端一站式提供商&#xff0c;亿道信息跟紧时代潮流&#xff0c;推出EM-I10J、EM-I20J两款均衡型加固平板&#xff0c;为行业发展注入新动力。 接地…...

Gemma谷歌(google)开源大模型微调实战(fintune gemma-2b)

Gemma-SFT Gemma-SFT(谷歌, Google), gemma-2b/gemma-7b微调(transformers)/LORA(peft)/推理 项目地址 https://github.com/yongzhuo/gemma-sft全部weights要用fp32/tf32, 使用fp16微调十几或几十的步数后大概率lossnan;(即便layer-norm是fp32也不行, LLaMA就没有这个问题, …...

MySQL:数据库中有哪些锁

1、全局锁 加上全局锁后整个数据库就处于只读状态了&#xff0c;这时其他线程执行以下操作&#xff0c;都会被阻塞&#xff1a; 对数据的增删改操作&#xff0c;比如 insert、delete、update等语句&#xff1b;对表结构的更改操作&#xff0c;比如 alter table、drop table 等…...

MWC 2024丨美格智能发布全新5G-A模组及FWA解决方案,将5.5G带入现实

2月26日&#xff0c;在MWC 2024世界移动通信大会上&#xff0c;美格智能正式宣布推出5G-A模组SRM817WE以及全新的5G-A FWA解决方案&#xff0c;包含5G-A CPE解决方案SRT858M、5G-A MiFi解决方案SRT878H和5G-A ODU解决方案SRT853MX&#xff0c;旨在进一步提升网络性能&#xff0…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器

一.自适应梯度算法Adagrad概述 Adagrad&#xff08;Adaptive Gradient Algorithm&#xff09;是一种自适应学习率的优化算法&#xff0c;由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率&#xff0c;适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

现代密码学 | 椭圆曲线密码学—附py代码

Elliptic Curve Cryptography 椭圆曲线密码学&#xff08;ECC&#xff09;是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础&#xff0c;例如椭圆曲线数字签…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案

JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停​​ 1. ​​安全点(Safepoint)阻塞​​ ​​现象​​:JVM暂停但无GC日志,日志显示No GCs detected。​​原因​​:JVM等待所有线程进入安全点(如…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...

算法:模拟

1.替换所有的问号 1576. 替换所有的问号 - 力扣&#xff08;LeetCode&#xff09; ​遍历字符串​&#xff1a;通过外层循环逐一检查每个字符。​遇到 ? 时处理​&#xff1a; 内层循环遍历小写字母&#xff08;a 到 z&#xff09;。对每个字母检查是否满足&#xff1a; ​与…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...