C++ 类型转换详解【建议收藏】

举报
Linux猿 发表于 2021/09/30 16:58:24 2021/09/30
【摘要】 C++ 类型转换详解

🎈 作者:Linux猿

🎈 简介:CSDN博客专家🏆,华为云享专家🏆,C/C++、面试、刷题、算法尽管咨询我,关注我,有问题私聊!

🎈 欢迎小伙伴们点赞👍、收藏⭐、留言💬


这篇文章主要对C++的类型转换作一个总结。

这里顺便提一下C语言的类型转换:

C语言的类型转换比较简单粗暴,分为隐式类型转换和显示类型转换。

隐式类型转换规则:

算数运算式中,低类型转化为高类型;

赋值表达式中,表达式的值转换为左边变量的类型;

函数调用时,实参转换为形参的类型;

函数返回值,return表达式转换为返回值类型;

类型转换1.png

显示类型转换格式:(type-id)expression

    C风格的类型转换有不少缺点,有的时候C风格的转换时不合适的,因为它可以在任意类型之间转换,比如可以把一个指向const对象的指针转换成指向非const对象的指针,把一个指向基类对象的指针转换成指向一个派生类对象的指针,这两种转换之间的差别是巨大的,但是传统的C语言风格的类型转换没有区分这些。还有一个缺点就是,C风格的转换不容易查找,他由一个括号加上标识符组成,而这样的东西在C++程序里一大堆。所以C++为了克服这些缺点,引进了4中新的类型转换操作符。

1.静态类型转换—static_cast

1.1 格式

static_cast<type-id>(expression)

    static_cast主要用于基本类型之间、基本类型指针和空指针间的转换(不能用于基本类型指针之间的转换),该运算符把expression转换为type-id类型,但是没有运行时类型检查来保证转换的安全性。

1.2 规则

用于类层次结构中基类和子类之间指针或引用的转换,可以进行上行转换(把子类的指针或引用转换成基类表示)是安全的和下行转换(把基类指针或引用转换成子类表示)式,由于没有动态类型检查,所以是不安全的;
用于基本数据类型之间的转化(编译器隐式执行的类型转换都可以用它来转换),例如:int与char,int 与float等。这种转换的安全性也需要开发人员来保证;
把空指针转换成目标类型的空指针;
把任何类型的表达式转换成void类型;
static_cast不能转换掉expression的const、volitale、或者_unaligned属性;
2. 动态类型转换—dynamic_cast

2.1 格式

dynamic_cast<type-id>(expression)


    dynamic_cast主要用于类层次结构中父类和子类之间指针和引用的转换,由于具有运行时类型检查,因此可以保证下行转换的安全性,安全性是指:转换成功就返回转换后的正确类型指针,如果转换失败,则返回NULL,之所以说static_cast在下行转换时不安全,是因为即使转换失败,它也不返回NULL。

2.2 规则

dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换;
在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;
在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全;
如果type-id是类指针类型,那么expression也必须是一个指针,如果type-id是一个引用,那么expression也必须是一个引用;
3. 重解释类型转换—reinterpret_cast

3.1 格式

reinterpret_cast<type-id>(expression)

3.2 规则

reinterpret_cast用在任意指针(或引用)类型之间的转换,以及指针与足够大的整数类型之间的转换;从整数类型(包括枚举类型)到指针类型,无视大小。type-id必须是一个指针、引用、算数类型、函数指针或成员指针。它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针。

4. 常类型转换—const_cast

4.1 格式

const_cast<type-id>(expression)

    用于修改类型的const或volatile属性。除了const或volatile修饰之外,type-id和expression的类型是一样的。使用const_cast 去除const 限定,通常是为了函数能够接受这个实际参数。

4.2 规则

常量指针被转换为非常量的指针,并仍然指向原来的对象;

常量引用被转换为非常量的引用,并仍然指向原来的对象;

const_cast一般用于修改底指针。如const char *p形式;

#include <iostream>
using namespace std;
 
int main(){
    const int g = 20;
    int &h = const_cast<int &>(g);
    cout<<"h = "<<h<<" &h = "<<&h<<endl;
    h = 10;
    cout<<"h = "<<h<<" &h = "<<&h<<endl;
    cout<<"g = "<<g<<" &g = "<<&g<<endl;
}

输出结果:

类型转换2.png

虽然能够改变h的值,指针也指向原来的对象,但是两个变量的值不一样。说明C++里const定义的值是不会改变的。IBM的C++指南称“h = 10”为“未定义行为”。所谓未定义,是说这个语句在标准C++中没有明确的规定。

参考文献:

[1] https://blog.csdn.net/qq_26849233/article/details/62218385

[2] https://www.cnblogs.com/TenosDoIt/p/3175217.html

[3] https://www.cnblogs.com/chenyangchun/p/6795923.html

[4] https://blog.csdn.net/QCZTZSWT357/article/details/73350688


🎈 有任何疑问欢迎交流!

🎈 欢迎小伙伴们点赞👍、收藏⭐、留言💬


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。