2.2 const_cast
主要用来去掉const和volatileness属性,大多数情况下是用来去掉const限制。
2.3 dynamic_cast
它用于安全地沿着继承关系向下进行类型转换。一般使用dynamic_cast把指向基类指针或者引用转换成其派生类的指针或者引用,并且当转换失败时候,会返回空指针。
2.4 reinterprit_cast
该转换最普通用途就是在函数指针类型之间进行转换。
1 typedef void (*fun) ( ) //一个指向空函数的指针 2 fun funArray[10]; //含有10个函数指针的数据。 3 int function( ); //一个返回值为int类型函数 4 funArray[0] = &function( ) //错误!类型不匹配 5 funArray[0] = reinterpret_cast<fun>(&function); //ok |
注意转换函数指针的代码是不可移植的。一般应该避免去转换函数指针类型。
3、使用非成员函数可以发生隐式转换
C++是支持隐式类型转换的,例如在做运算的时候,或者传递参数给函数的时候常常会发生隐式类型转换。
假设你设计一个class用来表现有理数。其实令类支持隐式类型转换是一个槽糕的决定。当然在建立数值类型时就是例外。下面定义一个有理数类型:
class Rational { public: Rational( int numerator = 0,int denominator =1 ); int numerator( ) const; int denominator ( ) const ; private: ... } |
有理数类型想当然支持算数运算,但是不确定是否声明为成员函数或非成员函数或者是友元函数来实现它们。
首先是考虑成员函数写法:
class Rational { public: ... const Rational operator* (const Rational& rhs) const; ... } Rational testOne(1,4); Rational testTwo(1,1); //做算术运算 Rational result = testOne * testTwo; //与常量做运算 result = testOne * 2; //ok //乘法满足交换定律 result = 2 * testOne //error!! |
那么为什么将常量提前就错误了呢?这里我们换一种写法
1 result = testOne.operator*(2); //ok 2 result =2.operator*(oneHalf); //error |
这里发生了什么?其实在第一行式子里发生了所谓隐式类型转换。哪里发生了隐式类型转换呢?看上面的代码operator*函数参数是const Rational类型,而2是一个cosnt int类型,。编译器发现有non-explicit型的单参数类为int类型的构造函数,可以造出Rational类型。所以编译器那样做了,发生了隐式类型转换。所以第一个式子可以正常运行,但是第二个是没有将Rational类型转换为int类型的。