c++ 显示类型转换

c++引入了4个新的强制类型转换操作符,static_cast、dynamic_cast、const_cast、reinterpret_cast,用以支持更为精细的类型转换。这些操作符取代了以往小圆括号所代表的旧式转型,能够清楚阐明转型的目的。这些新式转型操作符给了编译器更多信息,让编译器清楚知道转型的理由,并在转型失败时释出一份错误报告。

1. static_cast

static_cast在功能上基本上与C风格的类型转换一样强大,所以它是4个操作符中最常用的那个。但它也有功能上的限制,例如static_cast 不能从表达式中去除const属性(这是const_cast的工作)。

int firstNumber, secondNumber;
...
double result = ((double)firstNumber)/secondNumber;
double result = static_cast<double>(firstNumber)/secondNumber;

2. dynamic_cast

用于安全地沿着类的继承关系向下进行类型转换。这就是说,能用dynamic_cast把指向基类的指针或引用转换成指向其派生类或其兄弟类的指针或引用,而且能知道转换是否成功。失败的转换将返回空指针(当对指针进行类型转换时)或者抛出异常(当对引用进行类型转换时)。

Widget *pw;
...
update(dynamic_cast<SpecialWidget*>(pw));
void updateViaRef(SpecialWidget& rsw);
updateViaRef(dynamic_cast<SpecialWidget&>(*pw));

3. const_cast

const_cast 用于设置或去除表达式的const或 volatileness属性。

class Widget { ... };
class SpecialWidget: public Widget { ... };
void update(SpecialWidget *psw);

SpecialWidget sw; // sw是一个非const对象。
const SpecialWidget& csw = sw; // csw是sw的一个引用
                               // 它是一个const 对象  

update(&csw);  // 错误!不能传递一个const SpecialWidget* 变量
               // 给一个处理SpecialWidget*类型变量的函数  

update(const_cast<SpecialWidget *>(&csw));
               // 正确,csw的const被显示地转换掉
               //(csw和sw两个变量值在update函数中能被更新)

4. reinterpret_cast

使用这个操作符的类型转换,其转换结果几乎都是执行期定义(implementation-defined)。可能重新解释bits意义,也可能不是。因此,使用reinterpret_casts的代码很难移植,慎用reinterpret_cast。

reinterpret_casts的最普通的用途就是在函数指针类型之间进行转换。 例如,假设有一个函数指针数组:

typedef void (*FuncPtr)();  // FuncPtr是一个指向函数的指针,该函数没有参数
                            // 返回值类型为 void
FuncPtr funcPtrArray[10];   // funcPtrArray 是一个能容纳 10 个FuncPtrs指针的数组

假设希望(因为某些莫名其妙的原因)把一个指向下面函数的指针存入funcPtrArray数组:

int doSomething();

不能不经过类型转换而直接去做,因为 doSomething 函数对于funcPtrArray 数组来说是一个错误的类型。在FuncPtrArray 数组里的函数返回值是void类型,而doSomething 函数返回值是int类型。

funcPtrArray[0] = &doSomething;  //  错误!类型不匹配  
reinterpret_cast可以迫使编译器以你的方法去看待它们:
funcPtrArray[0] = // this compiles
  reinterpret_cast<FuncPtr>(&doSomething);

转换函数指针的代码是不可移植的(C++不保证所有的函数指针都被用一样的方法表示),在一些情况下这样的转换会产生不正确的结果,所以应该避免转换函数指针类型,除非你处于着背水一战和尖刀架喉的危急时刻。

【学习资料】 《c++ primer》 《more effective c++》 《c++标准程序库》

posted on 2013-02-01 17:46  zhuyf87  阅读(805)  评论(0编辑  收藏  举报

导航