为了让你对”参数的显式型转换“了解更透彻,C++引入以下四个新的操作符。
1. static_cast
将一个值以符合逻辑的方式转换。这可看做是”利用原值重建一个临时对象,并在设立初值时使用型别转换“。唯有当上述的型别转换有所定义,整个转换才会成功。所谓的”有所定义“,可以是语言内建规则,也可以是程序员自定的转换动作。例如:
float x;
...
cout << static_cast<int>(x); // print x as int
..
f(static_cast<string> ("hello")); // call f() for string instead of char *
2. dynamic_cast
将多态型别(polymorphic type)向下转型(downcast)为其实际静态型别(real static type)。这是唯一在执行期进行检验的转换动作。你可以用它来检验某个多态对象的型别,例如:
class Car; // abstract base class (has at least one virtual function)
class Cabriolet: public Car{
...
};
class Limousine :public Car{
...
};
void f(Car * cp)
{
Cabriolet *p = dynamic_cast<Cabriolet*>cp;
if(NULL == p){
// did not refer to an object of type Cabriolet
...
}
}
在这个例子中,面对实际静态型别为Cabriolet的对象,f()有特殊应对行为。当参数是个reference,而且型别转换失败时,dynamic_cast会丢出一个bad_cast异常。注意,从设计角度而言,你应该在运用多态技术的程序中,避免这种”程序行为取决于具体型别“的写法。
3.const_cast
设定或去除型别的常数性(constness),亦可去除volatile饰词。除此之外不允许任何转换。
4.reinterpret_cast
此操作符的行为由实际编译器定义。可能重新解释bits意义,但也不一定如此。使用此一转换动作通常带来不可转移性。
这些操作符取代了以往小括号所代表的旧式转型,能够清楚阐明转型的目的。小括号转型可替换dynamic_cast之外的其它三种转型,也因此当你运用它时,你无法明确显示使用它的确切理由。这些新式转型操作符给了编译器更多信息,让编译器清楚知道转型的理由,并在转型失败时释放出一份错误报告。
注意,这些操作符只接受一个参数。试看以下例子:
staitc_cast<Fraction> (15,100) //Oops , create Fraction(100)
在这个例子中你得不到你想要的结果,它只用一个数值100,将Fraction暂时对象设定初值,而非设定分子15,分母100。逗号在这里并不起分隔作用,而是形成一个comma(逗号)操作符,将两个表达式组合为一个表达式,并传回第二表达式作为最终结果。将15和100”转换“为分数的正确做法是:
Fraction(15,100) //fine ,creates Fraction(15,100)