【C++航海王:追寻罗杰的编程之路】C++的类型转换

目录

1 -> C语言中的类型转换

2 -> 为什么C++需要四种类型转换

3 -> C++强制类型转换

3.1 -> static_cast

3.2 -> reinterpret_cast

3.3 -> const_cast

3.4 -> dynamic_cast

4 -> RTTI


1 -> C语言中的类型转换

在C语言中,如果赋值运算符左右两侧类型不同,或者形参与实参类型不匹配,或者返回值类型与接收返回值类型不一致时,就需要发生类型转换,C语言中总共有两种形式的类型转换:

  1. 隐式类型转换:编译器在编译阶段自动进行,能转就转,不能转就编译失败。
  2. 显式类型转换:需要用户自己处理。
#define  _CRT_SECURE_NO_WARNINGS 1#include <iostream>
#include <stdio.h>
using namespace std;void Test()
{int i = 1;// 隐式类型转换double d = i;printf("%d, %.2f\n", i, d);int* p = &i;// 显示的强制类型转换int address = (int)p;printf("%x, %d\n", p, address);
}int main()
{Test();return 0;
}

缺陷:

转换的可视性比较差,所有的转换形式都是以一种相同的形式书写,难以跟踪错误的转换。

2 -> 为什么C++需要四种类型转换

C风格的转换格式很简单,但是缺点也不少:

  1. 隐式类型转换有些情况下可能会出问题:比如数据精度丢失。
  2. 显式类型转换将所有情况混合在一起,代码不够清晰。

因此C++提出了自己的类型转换风格,注意:因为C++要兼容C语言,所以C++中还可以使用C语言的转换风格。

3 -> C++强制类型转换

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

  • static_cast
  • reinterpret_cast
  • const_cast
  • dynamic_cast

3.1 -> static_cast

static_cast用于非多态类型的转换(静态转换),编译器隐式执行的任何类型转换都可用static_cast,但它不能用于两个不相关的类型进行转换。

#define  _CRT_SECURE_NO_WARNINGS 1#include <iostream>
using namespace std;int main()
{double d = 12.34;int a = static_cast<int>(d);cout << a << endl;return 0;
}

3.2 -> reinterpret_cast

reinterpret_cast操作符通常为操作数的位模式提供较低层次的重新解释,用于将一种类型转换为另一种不同的类型。

#define  _CRT_SECURE_NO_WARNINGS 1#include <iostream>
using namespace std;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;
}

3.3 -> const_cast

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

#define  _CRT_SECURE_NO_WARNINGS 1#include <iostream>
using namespace std;int main()
{const int a = 2;int* p = const_cast<int*>(&a);*p = 3;return 0;
}

3.4 -> dynamic_cast

dynamic_cast用于将一个父类对象的指针/引用转换为子类对象的指针/引用(动态转换)

  • 向上转型:子类对象指针/引用 -> 父类指针/引用(不需要转换,赋值兼容规则)。
  • 向下转型:父类对象指针/引用 -> 子类指针/引用(用dynamic_cast转型是安全的)。

注意:

  1. dynamic_cast只能用于父类含有虚函数的类。
  2. dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回0。
#define  _CRT_SECURE_NO_WARNINGS 1#include <iostream>
using namespace std;class A
{
public:virtual void f() {}
};class B : public A
{};void fun(A* pa)
{// dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回B* pb1 = static_cast<B*>(pa);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;
}

注意:

强制类型转换关闭或挂起了正常的类型检查,每次使用强制类型转换前,程序员应该仔细考虑是否还有其他不同的方法达到同一目的,如果非强制类型转换不可,则应限制强制类型转换值的作用域,以减少发生错误的机会。强烈建议:避免使用强制类型转换。

4 -> RTTI

RTTI:Run-time Type identification的简称,即:运行时类型识别。

C++通过以下方式来支持RTTI:

  1. typeid运算符
  2. dynamic_cast运算符
  3. decltype

感谢各位大佬支持!!!

互三啦!!!

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

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

相关文章

Java | Leetcode Java题解之第9题回文数

题目&#xff1a; 题解&#xff1a; class Solution {public boolean isPalindrome(int x) {// 特殊情况&#xff1a;// 如上所述&#xff0c;当 x < 0 时&#xff0c;x 不是回文数。// 同样地&#xff0c;如果数字的最后一位是 0&#xff0c;为了使该数字为回文&#xff0…

一些Java面试题

1、 Java语言有哪些特点 1、简单易学、有丰富的类库 2、面向对象&#xff08;Java最重要的特性&#xff0c;让程序耦合度更低&#xff0c;内聚性更高&#xff09; 3、与平台无关性&#xff08;JVM是Java跨平台使用的根本&#xff09; 4、可靠安全 5、支持多线程 2、面向对象和…

错误:找不到或无法加载主类(vscode的解决方法)

项目场景&#xff1a; 某天&#xff0c;喵某人在敲代码的过程中&#xff0c;点击运行代码&#xff0c;突然显示找不到或无法加载主类。之前创建的java文件都可以正常运行。但新建的java文件无论是什么&#xff0c;点击运行都会显示“错误&#xff1a;找不到或无法加载主类”。 …

初学python记录:力扣1483. 树节点的第 K 个祖先

题目&#xff1a; 给你一棵树&#xff0c;树上有 n 个节点&#xff0c;按从 0 到 n-1 编号。树以父节点数组的形式给出&#xff0c;其中 parent[i] 是节点 i 的父节点。树的根节点是编号为 0 的节点。 树节点的第 k 个祖先节点是从该节点到根节点路径上的第 k 个节点。 实现…

如何解决Redis和数据库的一致性问题?

为了保证Redis和数据库的数据一致性&#xff0c;肯定是要缓存和数据库双写了。 这时候就需要考虑两个问题&#xff1a;是先操作缓存还是先操作数据库&#xff1f;是删除缓存还是更新缓存&#xff1f; 我的建议是优先考虑删除缓存而不是更新缓存&#xff0c;因为删除缓存更加简单…

深度学习理论基础(六)多头注意力机制

目录 一、自定义多头注意力机制1. Scaled Dot-Product Attention2. 多头注意力机制框图&#xff08;1&#xff09;计算公式&#xff08;2&#xff09;具体计算过程&#xff08;3&#xff09;具体代码 二、pytorch中的子注意力机制模块 深度学习中的注意力机制&#xff08;Atten…

数据挖掘实战-基于LSTM算法的HCV检测者分类模型研究

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

VPDN(L2TP、PPTP)

1、虚拟专用拨号网络 远程接入VPN&#xff0c;客户端可以是PC机 技术&#xff1a;L2TP、PPTP 术语&#xff1a;LAC&#xff1a;L2TP的访问集中器 --- 提供用户的接入 LNS&#xff1a;L2TP的网络服务器 --- 提供L2TP服务的服务器 2、技术 1&#xff09;PPTP 点对点隧道…

Mysql启动失败解决过程

报错内容如下&#xff1a; Mar 05 18:40:49 VM-0-12-centos systemd[1]: Failed to start MySQL Server. Mar 05 18:40:49 VM-0-12-centos systemd[1]: Unit mysqld.service entered failed state. Mar 05 18:40:49 VM-0-12-centos systemd[1]: mysqld.service failed. Mar 05…

创建和启动线程

概述 Java语言的JVM允许程序运行多个线程&#xff0c;使用java.lang.Thread类代表线程&#xff0c;所有的线程对象都必须是Thread类或其子类的实例。 Thread类的特性 每个线程都是通过某个特定Thread对象的run()方法来完成操作的&#xff0c;因此把run()方法体称为线程执行体。…

刷题日记——由浅入深的大数加法(高精度加法)

例题 代码 #include <cstdio>int main(){long long a,b;scanf("%lld %lld",&a,&b);printf("%lld\n",ab);}例题——高精度加法 编程计算&#xff1a;12345678912345678912121211231212121212121212121222222111112121&#xff1f; 分析 加…

工程师必备:PW1558 12V/20V过流限压保护芯片,短路无忧,运行更稳定

在电力电子领域&#xff0c;寻找一款能够提供全面保护且性能卓越的电源开关至关重要。PW1558正是这样一款产品&#xff0c;它凭借出色的性能和广泛的应用领域&#xff0c;赢得了业界的广泛认可。下面&#xff0c;我们将从描述、特点和应用三个方面&#xff0c;详细解读PW1558的…