C++ 类型转换

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

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

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

隐式类型转换规则:

  • 算数运算式中,低类型转化为高类型;
  • 赋值表达式中,表达式的值转换为左边变量的类型;
  • 函数调用时,实参转换为形参的类型;
  • 函数返回值,return表达式转换为返回值类型;

                                           

                                                          图1 低类型转换为高类型

显示类型转换格式:(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;
}

输出结果:

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

Reference :

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Linux猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值