类型转换是一种让程序员能够暂时或永久性改变编译器对对象的解释机制。可改变对象解释方式的运算符称为类型转换运算符。
为何需要进行类型转换
通常为了实现使用不同环境的个人和厂商编写的模块能够相互调用和协作,程序员需要让编译器按照所需的方式解释数据,并成功编译和执行。一个非常经典的例子是:目前很多C++程序依然在使用很多年前用C编写的库,而针对这些C语言编译器编写的库必须依赖整形来保存布尔值,因此对于这些编译器来说,bool类型的定义就类似于:
typedef unsigned short BOOL,返回布尔值的函数可能这样声明:BOOL IsX()
而C++编译器支持bool,单位false和true。如果在新的C++应用程序中使用这样的库,程序员必须让其使用的C++编译器能够理解数据类型bool,同时让库能够理解数据类型bool,因此,可使用类型转换:bool bCPPResult = (bool) IsX();很明显这是C风格类型转换。而纯粹的C++语法论者认为这样的转换不伦不类,推崇纯粹的C++风格类型转换。
C++ 类型转换运算符
static_cast,dynamic_cast,reinterpret_cast,const_cast
完全相同的语法:destination_type result = cast_type <destination_type>(object_to_be_casted)
static_cast :
静态类型转换,实现编译阶段检查,确保指针转换为相关类型,可用于相关类型的指针之间进行转换,还可显式地执行标准数据类型的类型转换。在C语言中可将一个对象的指针转换为完全不相关的类型,而编译器不会报错。而是用static_cast则会对指针相关性进行检查,如果不相关,则编译器会报错。同时static_cast可以实现指针向上转换为基类类型,向下转换为派生类型,但不会在运行阶段执行检查。而通常向下转换为派生类型时,在运行阶段会有可能导致意外结果。因此便有了下面的动态类型转换。
dynamic_cast:
动态类型转换,在运行阶段执行类型转换,可检查操作结果,如果为NULL则转换失败。所以采用动态类型转换,一定要进行指针的判断。这种在运行阶段识别对象类型的机制称为运行阶段类型识别(RTTI,runtime type identification)
reinterpret_cast:
属于强制类型转换,与C风格类型转换最接近。不进行相关性判断,强制编译器接收static_cast通常不允许的类型转换,一般用于低级的驱动程序。一般不使用这种方式。
const_cast:
让程序员能够关闭对象的访问修饰符const。通常修改由于使用const引用来调用non-const成员函数编译导致的错误,利用const_cast把const引用转变为non-const引用,然后就可以顺利的编译和执行。
C++ 类型转换运算符存在的问题
在现代C++中,除了dynamic_cast之外的类型转换都是可以避免的,仅当需要满足遗留应用程序需求时,才需要使用其他类型转换运算符。重要的是,一旦使用类型转换,务必要知道幕后发生的情况。
在使用中应牢记:将派生类转换为基类类型叫做向上转换,是安全的;将基类类型转换为派生类类型叫做向下转换,除非使用dynamic_cast否者是不安全的;请牢记,创建继承层次结构时,应尽量将函数声明为虚函数,这样通过基类指针调用这些函数时,如果该指针指向的是派生类对象,将调用相应类的函数版本;在使用dynamic_cast别忘了对指针进行检查,看其是否有效。