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

C++---类型转换

文章目录

  • C++的类型转换
    • C++的4种强制类型转换
    • RTTI

C++的类型转换

  • 类型转换

    • 内置类型之间的转换

      // a、内置类型之间
      // 1、隐式类型转换    整形之间/整形和浮点数之间
      // 2、显示类型的转换  指针和整形、指针之间
      int main()
      {int i = 1;// 隐式类型转换double d = i;printf("%d, %.2f\n", i, d);int* p = &i;// 显示的强制类型转换int address = (int)p;printf("%p, %d\n", p, address);return 0;
      }
      
    • 内置类型与自定义类型之间的类型转换

      • 内置类型转自定义类型:通过 自定义类型的 构造函数,使得内置类型可以转换为自定义类型

      • 自定义类型转内置类型:通过operator语法来实现 自定义类型转换为 内置类型
        operator + 允许类型转换的类型(),该语法比较特殊,不用写返回值,但是函数体有返回值,返回值类型是 允许类型转换的类型

      • 样例

        // b、内置类型和自定义类型之间
        // 1、自定义类型 = 内置类型  ->构造函数支持
        // 2、内置类型 = 自定义类型
        class A
        {
        public://explicit A(int a)A(int a):_a1(a),_a2(a){}A(int a1, int a2):_a1(a1), _a2(a2){}// ()被仿函数占用了,不能用// operator 类型实现,无返回类型//explicit operator int() //explicit关键字是禁止隐式类型转换,此处是禁止 A 隐式类型转换为 intoperator int(){return _a1 + _a2;}
        private:int _a1 = 1;int _a2 = 1;
        };
        int main()
        {string s1 = "1111111";//这就是 内置类型 通过 构造函数 隐式类型转化为 string 类型A aa1 = 1;//A aa1 = (A)1;A aa2 = { 2,2 };const A& aa3 = { 2,2 };int z = aa1.operator int();//int x = (int)aa1;int x = aa1;int y = aa2;cout << x << endl;cout << y << endl;std::shared_ptr<int> foo;std::shared_ptr<int> bar(new int(34));//if (foo.operator bool())if (foo)std::cout << "foo points to " << *foo << '\n';else std::cout << "foo is null\n";if (bar)std::cout << "bar points to " << *bar << '\n';elsestd::cout << "bar is null\n";return 0;
        }
        
    • 自定义类型与自定义类型之间的类型转换:通过对应的构造函数支持

      // c、自定义类型和自定义类型之间 -- 对应的构造函数支持
      class A
      {
      public:A(int a):_a1(a), _a2(a){}A(int a1, int a2):_a1(a1), _a2(a2){}int get() const{return _a1 + _a2;}
      private:int _a1 = 1;int _a2 = 1;
      };class B
      {
      public:B(int b):_b1(b){}B(const A& aa):_b1(aa.get()){}private:int _b1 = 1;
      };
      

C++的4种强制类型转换

标准C++为了加强类型转换的可视性,引入了四种命名的强制类型转换操作符:static_cast、reinterpret_cast、const_cast、dynamic_cast

  • static_cast

    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操作符通常为操作数的位模式提供较低层次的重新解释,用于将一种类型转换 为另一种不同的类型。即reinterpret_cast对应强制类型转换,数据的意义已经发生改变

    语法:reinterpret_cast<要隐式转为的类型>(被转的变量);

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

    const_cast最常用的用途就是删除变量的const属性,方便赋值

    对应强制类型转换中有风险的去掉const属性的操作

    语法:const_cast<要隐式转为的类型>(被转的变量);
    volatile 修饰const变量,表明取变量的值时是去内存中去。 const 变量 正常情况下是被编译器用宏替代的/取值时从寄存器中取的。

    int main()
    {// 对应隐式类型转换 -- 数据的意义没有改变double d = 12.34;int a = static_cast<int>(d);// 对应强制类型转换中有风险的去掉const属性volatile const int b = 2;//此处如果没有volatile修饰,那么下文打印的b的结果还是2,但是实际上调试等操作可以看到b在内存中的值已经被修改了,那为什么打印出来是2呢?因为vs优化 const变量是直接被宏替代的,这个过程是编译过去中进行的,而改变b的值的操作是运行时进行的。int* p2 = const_cast<int*>(&b);*p2 = 3;cout << b << endl;cout << *p2 << endl;return 0;
    }
    
  • dynamic_cast

    dynamic_cast用于将一个父类对象的指针/引用转换为子类对象的指针或引用(动态转换) 。 即 dynamic_cast 用于 父类和子类之间的转换

    父类和子类之间转换分为两种
    **向上转型:子类对象指针/引用->父类指针/引用(不需要转换,赋值兼容规则) **

    向下转型:父类对象指针/引用->子类指针/引用(用dynamic_cast转型是安全的)

    dynamic_cast使用的范围:dynamic_cast只能用于父类含有虚函数的类

    优点:dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回0
    怎么算成功?怎么算不成功呢?
    *向上转型是赋值兼容规则,都是兼容的。 对于向下转型而言, 如果进行转换的指针/引用本身是指向父类的指针(注意:这里不是指 指针的类型,而是指 指针的指向的对象),那么它就会转换失败【失败的原因:对一个本来指向父类的指针进行强转为指向子类的指针,这就对父类添加了子类成员构造成了子类,存在风险】。如果进行转换的指针/引用本身是指向子类的指针

    class A
    {
    public:virtual void f() {}
    };
    class B : public A
    {};
    void fun(A* pa)
    {// dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回B* pb1 = static_cast<B*>(pa);//其实reinterpret_cast也能转换,但是不安全,因为它们不会对其进行检查B* pb2 = dynamic_cast<B*>(pa);cout << "pb1:" << pb1 << endl;cout << "pb2:" << pb2 << endl;
    }
    int main()
    {A a;B b;fun(&a);fun(&b);return 0;
    }
    

RTTI

  • 概念:RTTI是指 运行时类型识别
  • C++通过以下方式来支持RTTI
    1. typeid运算符:返回字面为数据的类型的字符串。(即int类型转换成"int")
    2. dynamic_cast运算符
    3. decltype

相关文章:

C++---类型转换

文章目录 C的类型转换C的4种强制类型转换RTTI C的类型转换 类型转换 内置类型之间的转换 // a、内置类型之间 // 1、隐式类型转换 整形之间/整形和浮点数之间 // 2、显示类型的转换 指针和整形、指针之间 int main() {int i 1;// 隐式类型转换double d i;printf("%d…...

CSS基础学习练习题

编程题 1.为下面这段文字定义字体样式&#xff0c;要求字体类型指定多种、大小为14px、粗细为粗体、颜色为蓝色。 “有规划的人生叫蓝图&#xff0c;没规划的人生叫拼图。​” 代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><me…...

TypeScript知识点总结和案例使用

TypeScript 是一种由微软开发的开源编程语言&#xff0c;它是 JavaScript 的超集&#xff0c;提供了静态类型检查和其他一些增强功能。以下是一些 TypeScript 的重要知识点总结&#xff1a; 1. 基本类型 TypeScript 支持多种基本数据类型&#xff0c;包括&#xff1a; numbe…...

解决BUG: Since 17.0, the “attrs“ and “states“ attributes are no longer used.

从Odoo 17.0开始&#xff0c;attrs和states属性不再使用&#xff0c;取而代之的是使用depends和domain属性来控制字段的可见性和其他行为。如果您想要在选择国家之后继续选择州&#xff0c;并且希望在选择了国家之后才显示州字段&#xff0c;您可以使用depends属性来实现这一点…...

单片机GPIO中断+定时器 实现模拟串口接收

单片机GPIO中断定时器 实现模拟串口接收 解决思路代码示例 解决思路 串口波特率9600bps,每个bit约为1000000us/9600104.16us&#xff1b; 定时器第一次定时时间设为52us即半个bit的时间&#xff0c;其目的是偏移半个bit时间&#xff0c;之后的每104us采样并读取1bit数据。使得…...

《深入理解 Spring MVC 工作流程》

一、Spring MVC 架构概述 Spring MVC 是一个基于 Java 的轻量级 Web 应用框架&#xff0c;它遵循了经典的 MVC&#xff08;Model-View-Controller&#xff09;设计模式&#xff0c;将请求、响应和业务逻辑分离&#xff0c;从而构建出灵活可维护的 Web 应用程序。 在 Spring MV…...

HTML简介

知识点一 HTML 什么是HTML&#xff1f; 超文本标记语言(HyperTextMarkup Language&#xff0c;简称HTML) 怎么学HTML&#xff1f; HTML 是一门标记语言&#xff0c;标记语言由一套标记标签组成&#xff0c;学习 HTML&#xff0c;其实就是学习标签 开发工具 编辑器: Pycha…...

Linux系统Centos设置开机默认root用户

目录 一. 教程 二. 部分第三方工具配置也无效 一. 教程 使用 Linux 安装Centos系统的小伙伴大概都知道&#xff0c;我们进入系统后&#xff0c;通常都是自己设置的普通用户身份&#xff0c;而不是 root 超级管理员用户&#xff0c;导致我们在操作文件夹时往往爆出没有权限&am…...

【网络安全 | 甲方建设】双/多因素认证、TOTP原理及实现

未经许可,不得转载。 文章目录 背景双因素、多因素认证双因素认证(2FA)多因素认证(MFA)TOTP实现TOTP生成流程TOTP算法TOTP代码示例(JS)Google Authenticator总结背景 在传统的在线银行系统中,用户通常只需输入用户名和密码就可以访问自己的账户。然而,如果密码不慎泄…...

Nuxt3 动态路由URL不更改的前提下参数更新,NuxtLink不刷新不跳转,生命周期无响应解决方案

Nuxt3 动态路由URL不更改的前提下参数更新&#xff0c;NuxtLink不刷新不跳转&#xff0c;生命周期无响应解决方案 首先说明一点&#xff0c;Nuxt3 的动态路由响应机制是根据 URL 是否更改&#xff0c;参数的更改并不会触发 Router 去更新页面&#xff0c;这在 Vue3 上同样存在…...

2024华为java面经

华为2024年Java招聘面试题目可能会涵盖Java基础知识、核心技术、框架与工具、项目经验以及算法与数据结构等多个方面。以下是考的内容。 一、Java基础知识 Java中有哪些基本数据类型&#xff1f; Java为什么能够跨平台运行&#xff1f; String是基本数据类型吗&#xff1f;能…...

2021 年 9 月青少年软编等考 C 语言三级真题解析

目录 T1. 课程冲突思路分析T2. 余数相同问题思路分析T3. 生成括号思路分析T4. 广义格雷码思路分析T5. 菲波那契数列思路分析T1. 课程冲突 小 A 修了 n n n 门课程,第 i i i 门课程是从第 a i a_i ai​ 天一直上到第 b i b_i bi​ 天。 定义两门课程的冲突程度为:有几天…...

深度解析FastDFS:构建高效分布式文件存储的实战指南(下)

接上篇&#xff1a;《深度解析FastDFS&#xff1a;构建高效分布式文件存储的实战指南&#xff08;上&#xff09;》 传送门: link 文章目录 六、常用命令七、FastDFS配置详解7.1 tracker配置文件7.2 tracker目录及文件结构7.3 storage配置文件7.4 storage服务器的目录结构和文件…...

Python学习29天

二分查找 # 定义函数冒泡排序法从大到小排列 def bbble_sort(list):# i控制排序次数for i in range(len(list) - 1):# j控制每次排序比较次数for j in range(len(list) - 1 - i):if list[j] < list[j 1]:list[j], list[j 1] list[j 1], list[j] # 定义二分查找函数 def…...

Soul App创始人张璐团队携多模态大模型参加GITEX GLOBAL,展现未来社交趋势

作为中东地区规模最大、最成功的计算机通讯及消费性电子产品展,GITEX GLOBAL一直颇受全球关注,于今年迎来了第44届盛会。自诞生以来,GITEX GLOBAL始终聚焦技术驱动的创新,吸引了许多科技巨头、创新企业及投资者的参与。Soul App作为中国较早将AI技术引入社交的企业,今年首次亮相…...

简单工厂模式、方法工厂模式

简单工厂模式&#xff08;Simple Factory Pattern&#xff09; 简单工厂模式的核心思想是通过一个工厂类&#xff0c;根据提供的参数来决定创建哪一个具体的产品类实例。 这个模式通常用于产品种类较少&#xff0c;且不经常变化的场景。 interface Product {void create(); }…...

【面试】前端vue项目架构详细描述

基于您提供的技术栈和要求&#xff0c;以下是前端项目的架构设计描述&#xff1a; 项目结构 • 入口文件&#xff1a; main.js 作为项目的入口文件&#xff0c;负责初始化 Vue 实例&#xff0c;并挂载到 DOM 上。 • 组件目录&#xff1a; components 目录包含项目的所有 Vue 组…...

BERT的中文问答系统32

我们需要在现有的代码基础上增加网络搜索功能&#xff0c;并在大模型无法提供满意答案时调用网络搜索。以下是完整的代码和文件结构说明&#xff0c;我们创建一个完整的项目结构&#xff0c;包括多个文件和目录。这个项目将包含以下部分&#xff1a; 主文件 (main.py)&#xf…...

大数据-226 离线数仓 - Flume 优化配置 自定义拦截器 拦截原理 拦截器实现 Java

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; Java篇开始了&#xff01; 目前开始更新 MyBatis&#xff0c;一起深入浅出&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff0…...

idea maven 重新构建索引

当设置maven仓库为离线模式的时候&#xff0c;会出现一些问题。 比如本地的仓库被各种方式手动更新之后&#xff0c; 举例&#xff1a;我需要一个spring的包&#xff0c;在pmo文件中写好了引入包的代码 但是由于是离线模式没有办法触发自动下载&#xff0c;那么这个时候我可以…...

C#桌面应用制作计算器

C#桌面应用制作简易计算器&#xff0c;可实现数字之间的加减乘除、AC按键清屏、Del按键清除末尾数字、/-按键取数字相反数、%按键使数字缩小100倍、按键显示运算结果等...... 页面实现效果 功能实现 布局 计算器主体使用Panel容器&#xff0c;然后将button控件排列放置Pane…...

细说STM32单片机DMA中断收发RTC实时时间并改善其鲁棒性的方法

目录 一、DMA基础知识 1、DMA简介 (1)DMA控制器 (2)DMA流 (3)DMA请求 (4)仲裁器 (5)DMA传输属性 2、源地址和目标地址 3、DMA传输模式 4、传输数据量的大小 5、数据宽度 6、地址指针递增 7、DMA工作模式 8、DMA流的优先级别 9、FIFO或直接模式 10、单次传输或突…...

【Unity/Animator动画系统】多层动画状态机实现角色的基本移动

文章目录 前言实现顶层地面状态四方向混合树计算动画所需参数 空中状态分层动画 前言 最近打算做个Rougelike RPG 塔科夫 混搭风格的冒险游戏。暂且就当是一个有随机元素&#xff0c;有基地&#xff0c;死亡会掉落物品的近战塔科夫罢。 花了三天时间&#xff0c;整合了Mixa…...

每日算法一练:剑指offer——栈与队列篇(1)

1.图书整理II 读者来到图书馆排队借还书&#xff0c;图书管理员使用两个书车来完成整理借还书的任务。书车中的书从下往上叠加存放&#xff0c;图书管理员每次只能拿取书车顶部的书。排队的读者会有两种操作&#xff1a; push(bookID)&#xff1a;把借阅的书籍还到图书馆。pop…...

【Java】ArrayList与LinkedList详解!!!

目录 一&#x1f31e;、List 1&#x1f345;.什么是List&#xff1f; 2&#x1f345;.List中的常用方法 二&#x1f31e;、ArrayList 1&#x1f34d;.什么是ArrayList? 2&#x1f34d;.ArrayList的实例化 3&#x1f34d;.ArrayList的使用 4&#x1f34d;.ArrayList的遍…...

怎么用VIM查看UVM源码

利用ctags工具可以建立源码的索引表&#xff0c;在使用VIM或其他文本编辑器时&#xff0c;就可以跳转查看所调用的UVM或VIP的funtcion/task/class等源码了。 首先需要确认ctags安装&#xff0c;一般安装VIM后都有&#xff0c;如果没有可以手动安装。在VIM中可以输入:help ctag…...

数据结构C语言描述3(图文结合)--双链表、循环链表、约瑟夫环问题

前言 这个专栏将会用纯C实现常用的数据结构和简单的算法&#xff1b;有C基础即可跟着学习&#xff0c;代码均可运行&#xff1b;准备考研的也可跟着写&#xff0c;个人感觉&#xff0c;如果时间充裕&#xff0c;手写一遍比看书、刷题管用很多&#xff0c;这也是本人采用纯C语言…...

第二十五章 TCP 客户端 服务器通信 - TCP 设备的 READ 命令

文章目录 第二十五章 TCP 客户端 服务器通信 - TCP 设备的 READ 命令TCP 设备的 READ 命令READ 修改 $ZA 和 $ZB$ZA 和 READ 命令 第二十五章 TCP 客户端 服务器通信 - TCP 设备的 READ 命令 TCP 设备的 READ 命令 从服务器或客户端发出 READ 命令以读取客户端或服务器设置的…...

【C++】哈希表的实现详解

哈希表的实现详解 一、哈希常识1.1、哈希概念1.2、哈希冲突1.3、哈希函数&#xff08;直接定执 除留余数&#xff09;1.4、哈希冲突解决闭散列&#xff08;线性探测 二次探测&#xff09;开散列 二、闭散列哈希表的模拟实现2.1、框架2.2、哈希节点状态的类2.3、哈希表的扩容2…...

高阶C语言之五:(数据)文件

目录 文件名 文件类型 文件指针 文件的打开和关闭 文件打开模式 文件操作函数&#xff08;顺序&#xff09; 0、“流” 1、字符输出函数fputc 2、字符输入函数fgetc 3、字符串输出函数fputs 4、 字符串输入函数fgets 5、格式化输入函数fscanf 6、格式化输出函数fpr…...