C++通过引进四个新的类型转换操作符克服了C风格类型转换的缺点,这四个操作符是:
const_cast<T>( expression )
dynamic_cast<T>( expression )
static_cast<T>( expression )
reinterpret_cast<T>( expression )
在大多数情况下,对于这些操作符你只需要知道原来你习惯于这样写:
(type) expression
而现在你总应该这样写:
static_cast <type> (expression)
例如,假设你想把一个int转换成double,以便让包含int类型变量的表达式产生出浮点数值的结果。如果用C风格的类型转换,你能这样写:
int firstNumber, secondNumber;
double result = ((double)firstNumber)/secondNumber;
如果用上述新的类型转换方法,你应该这样写:
double result = static_cast<double>(firstNumber)/secondNumber;
这种形式十分容易被辨识出来,不论是对人类还是对工具程序而言。
这四个转型操作符各司其职:
1 static_cast
基本上拥有与C旧式转型相同的威力与意义,以及相同的限制。
用法:static_cast < type-id > ( expression )
该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法:
①用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。
进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;
进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。
②用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。
③把空指针转换成目标类型的空指针。
④把任何类型的表达式转换成void类型。
注意:static_cast不能转换掉expression的const、volitale、或者__unaligned属性。
例如将int转换为 double。
int testNum;
static_cast<double>testNum;
static_cast可以将一个非 const 的对象转换为 const 对象,但是他无法将const转为non-const,这个只有const-cast才能够办到。也不能将int或者struct转换成pointer,这个转换在c里面也是不允许的。
如果是一个类,就调用类型转换函数,比如:
2 const_cast
通常用来将对象的常量性转除(cast away the constness)。它是唯一有此能力的C++-style转型操作符。
const int a =314;
a=2;//错误的
int *p = &a;
*p=3;//错误的
C++会报错,因为&a是const int *,不能将一个const指针或引用赋给指针或初始化引用。换成这样就行了:
int *p=const_cast<int*>(&a);
编译器放给了你这样的权力,如果你这样写,表明你能为它的后果负责。
现在我只需要记住。const_cast最重要的作用就是去除常量性。
3 dynamic_cast
用来执行继承体系中安全的向下转型或跨系转型动作。也就是说你可以利用它将指向基类对象的指针或者引用转型为指向派生类对象的指针或引用,并得知转型是否成功。不同于static_cast,dynamic_cast转换一个基类指针到子类指针的转型,会做动态类型检查,所以是安全的。如果转型失败,会以一个null指针(当转型对象是指针)或一个exception(当转型对象是引用)表现出来。dynamic_cast是唯一无法由旧式语法执行的转型动作,也是唯一可能消耗重大运行成本的转型动作。
上面的操作用dynamic_cast是可以支持的
A* pa = new AB;
Update(dynamic_cast<AB*>pa);
注意的是关于此操作符的返回值
如果表达式是pointer ,转换失败的话会得到一个NULL
如果............是ref,........................会抛出一个异常
dynamic_cast只能做这一类型的转换,请不要尝试去用dynamic_cast改变表达式的常量性,也无法在缺乏虚函数的型别上使用(比如int to double,这样的转换得使用static_cast)
运行结果:
D2.foo
D2.foo3
4 reinterpret_cast
意图执行低级转型,实际动作及结果可能取决于编译器,这也就表示它不可移植。例如将一个pointer to int 转型为int。这一类转型在低级代码以外很少见。
他最常用途是转换(函数指针)的型别
有一个保存函数指针的数组,里面指针指向函数的return 都是void
但是你现在有个函数return为int,这个时候如果你想把这个函数放进funcPtrArray
如果没有转型是可能实现的
typedefine void (*FuncPtr())
int func();
funcPtrArray[0] = &func;//错误,型别不对
funcPtrArray[0] = reinterpret_cast(FuncPtr)(&func);//正确
对于字节数相同的类型,例如整形和指针型,可以实现完全的按位转换。这意味着你可以把一个整数赋给一个指针,也可以把一个指针转换成整数,也可以实现各种不兼容指针的转换。
对于字节数不同的类型,这个操作符不能使用。例如
int x = reinterpret_cast <int> (3.14)
就是错误的
标准C++的类型转换
最新推荐文章于 2023-01-12 15:47:19 发布