C++转型操作符
C++通过引进四个新的类型转换操作符克服了C风格类型转换的缺点,这四个操作符是:
const_cast<T>( expression )
dynamic_cast<T>( expression )
static_cast<T>( expression )
reinterpret_cast<T>( expression )
在大多数情况下,对于这些操作符你只需要知道原来你习惯于这样写:
(type) expression
而现在你总应该这样写:
static_cast(expression)
例如,假设你想把一个int转换成double,以便让包含int类型变量的表达式产生出浮点数值的结果。如果用C风格的类型转换,你能这样写:
int firstNumber, secondNumber;
...
double result = ((double)firstNumber)/secondNumber;
如果用上述新的类型转换方法,你应该这样写:
double result = static_cast<double>(firstNumber)/secondNumber;
这种形式十分容易被辨识出来,不论是对人类还是对工具程序而言。
这四个转型操作符各司其职:
l const_cast 通常用来将对象的常量性转除(cast away the constness)。它是唯一有此能力的C++-style转型操作符。
l dynamic_cast用来执行继承体系中安全的向下转型或跨系转型动作。也就是说你可以利用它将指向基类对象的指针或者引用转型为指向派生类对象的指针或引用,并得知转型是否成功。如果转型失败,会以一个null指针(当转型对象是指针)或一个exception(当转型对象是引用)表现出来。dynamic_cast是唯一无法由旧式语法执行的转型动作,也是唯一可能消耗重大运行成本的转型动作。
l static_cast 基本上拥有与C旧式转型相同的威力与意义,以及相同的限制。例如将一个非 const的对象转换为 const 对象,或将int 转换为 double等等。它也可以用来执行上述多种转换的反向转换,例如将void*指针转为typed指针,将pointer-to-base转为pointer-to-derived。但是他无法将const转为non-const,这个只有const-cast才能够办到。
l reinterpret_cast意图执行低级转型,实际动作及结果可能取决于编译器,这也就表示它不可移植。例如将一个pointer to int 转型为int。这一类转型在低级代码以外很少见。
旧式转型在 C++ 中仍然是合法的,但是这里更推荐使用新形式。首先,它们在代码中更加易于辨认(不仅对人,而且对 grep 这样的工具也是如此),因而得以简化“找出类型系统在哪个地点被破坏”的过程。第二,各转型动作的目标愈窄化,编译器愈可能诊断出错误的运用。例如,如果你打算将常量性去掉,除非使用新式转型中的const_cast,否则无法通过编译。