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 :

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章