【C++】类型转换
创始人
2024-03-01 23:10:11
0

目录

一、C语言风格类型转换

二、C++风格类型转换

1.static_case

2.reinterpret_case

3、const_case

4、dynamic_case

三、RTTI

总结


一、C语言风格类型转换

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

1、隐式类型转换 :编译器在编译阶段自动进行,能转就转,不能转就编译失败

2、显示类型转换 :需要用户手动转换

无论是隐式类型转换还是显式类型转换,都是要产生临时对象的,并不会修改原来的对象

整型之间的转换 :由占用内存小的转换为大的叫做提升

大的转换成小的叫做截断

二、C++风格类型转换

C++提出自己的类型转换风格的原因是:

1、隐式类型转换可能在一定的情况下出现问题,例如精度丢失

2、显示类型转换将所有的情况都混合在一起,代码不够清晰,且具有一定的风险

C++提供了四种类型转换

1.static_case

static_case类似于上面的隐式类型转换,不能将两个不相关的类型进行转换

void test_static_case()
{int i = 0;double j = static_cast(i);double* m = reinterpret_cast(&i);
}

2.reinterpret_case

reinterpret_case类似与上面的强制类型转换,它通常为操作数的位模式提供较低层次的重新解释,用于将一种类型转换为另一种不同的类型

不过类型并不相关不能转换,就如同C语言的强制类型转换

void test_reinterpret_case()
{int* p = reinterpret_cast(new Node);Node n;int m = reinterpret_cast(n);
}

指针当然是没有问题的,不过下面的就会报错

 

3、const_case

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

它本质与reinterpret_case相同,都是强制类型转换,不过C++将其分离出来,目的是提醒,将会修改常量。

void test_const_case()
{const int a = 20;int* p = const_cast(&a);*p = 3;//跟vs下的情况类似cout << a << endl;cout << *p << endl;
}

我们使用了p去修改常量,那么输出结果是什么呢?

这时很多同学就会疑惑,为什么是20,3我明明已经修改了a的值?

这是因为a被声明为常量,编译器就会作出一定的优化,将a存储到寄存器或者直接变成宏,因为并不涉及到值的修改,而我们通过指针去修改a,修改的是在内存中的a,而在寄存器中保存的a的值并没有被影响,所以,输出结果是20,3

 

4、dynamic_case

dynamic_case并不属于C语言的两种类型转换的范畴,因为它并不会产生临时对象

dynamic_cast用于将一个父类对象的指针/引用转换为子类对象的指针或引用(动态转换) 在dynamic_case之前有两个概念 向上转型:子类对象指针/引用->父类指针/引用(不需要转换,赋值兼容规则) 向下转型:父类对象指针/引用->子类指针/引用(用dynamic_cast转型是安全的)

所谓的向上转换就是切片,派生类对象转换为基类对象

向下转换与向上转换相反,它是基类转换为派生类

在多态时我们知道,要传基类或者派生类,用基类的指针或者引用来接收,对于引用来说,这里并不考虑,因为C++默认不支持将一个类的对象赋值给另一个类

基类指针可能是指向基类也可能指向派生类,有时我们想要调用派生类自己的成员时,就需要将它强制转换为派生类指针,但是这种转换是不安全的,我们无法知道,指向的是基类还是派生类,如果指向的是基类,我们强制类型转换,就会出现越界的问题,所以为了区分这种情况,出现了dynamic_case

注意:

1. dynamic_cast只能用于父类含有虚函数的类 2. dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回0

class A
{
public:virtual void func() {}int _a = 0;
};class B : public A
{
public:int _b = 0;
};//func 是为了实现多态
void func(A* pa)
{B* pb = dynamic_cast(pa);if(pb){cout << "转换成功" << endl;cout << pb->_a << " : " << pb->_b << endl;}else{cout << "转换失败" << endl;cout << pa->_a << endl;}
}void test_dynatic_case()
{A a;B b;func(&a);func(&b);
}

 

三、RTTI

RTTI:Run-time Type identifification的简称,即:运行时类型识别。 C++通过以下方式来支持RTTI: 1. typeid运算符 2. dynamic_cast运算符 3. decltype


总结


以上就是今天要讲的内容,本文仅仅简单介绍了C++的类型转换

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
群晖外网访问终极解决方法:IP... 写在前面的话 受够了群晖的quickconnet的小水管了,急需一个新的解决方法&#x...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
Azure构建流程(Power... 这可能是由于配置错误导致的问题。请检查构建流程任务中的“发布构建制品”步骤,确保正确配置了“Arti...