转:
C
风格的类型转换:一来它们过于粗鲁,能允许你在任何类型之间进行转换。不过如果要进行更精确的类型转换,这会是一个优点。二来C风格的类型转换在程序语句中难以识别。
C++
通过引进四个新的类型转换操作符克服了C风格类型转换的缺点, static_cast, const_cast, dynamic_cast, 和reinterpret_cast。(type) expression ==》static_cast<type>(expression)
static_cast
在功能上基本上与C风格的类型转换一样强大,含义也一样。它也有功能上限制。例如,你不能用static_cast象用C风格的类型转换一样把struct转换成int类型或者把double类型转换成指针类型,
static_cast
不能从表达式中去除const属性,因为另一个新的类型转换操作符const_cast有这样的功能。
const_cast
用于类型转换掉表达式的const或volatileness属性。到目前为止,const_cast最普通的用途就是转换掉对象的const属性。
dynamic_cast
,它被用于安全地沿着类的继承关系向下进行类型转换。这就是说,你能用dynamic_cast把指向基类的指针或引用转换成指向其派生类或其兄弟类的指针或引用,而且你能知道转换是否成功。失败的转换将返回空指针(当对指针进行类型转换时)或者抛出异常(当对引用进行类型转换时)。dynamic_casts在帮助你浏览继承层次上是有限制的。它不能被用于缺乏虚函数的类型上(参见条款M24),也不能用它来转换掉constness。
如你想在没有继承关系的类型中进行转换,你可能想到static_cast。如果是为了去除const,你总得用const_cast。
dynamic_cast依赖于RTTI信息,其次,在转换时,dynamic_cast会检查转换的source对象是否真的可以转换成target类型,这种检查不是语法上的,而是真实情况的检查。
先看RTTI相关部分,通常,许多编译器都是通过vtable找到对象的RTTI信息的,这也就意味着,如果基类没有虚方法,也就无法判断一个基类指针变量所指对象的真实类型, 这时候,dynamic_cast只能用来做安全的转换,例如从派生类指针转换成基类指针.而这种转换其实并不需要dynamic_cast参与.
也就是说,dynamic_cast是根据RTTI记载的信息来判断类型转换是否合法的.
下面看一个例子:
struct B1{
virtual ~B1(){}
};
struct B2{
virtual ~B2(){}
};
struct D1 : B1, B2{};
int main()
{
D1 d;
B1* pb1 = &d;
B2* pb2 = dynamic_cast<B2*>(pb1);//L1
B2* pb22 = static_cast<B2*>(pb1); //L2
return 0;
}
上述定义中可以看到,B1和B2是不相关的类,从L1可以看到,dynamic_cast允许这种转换:只要B1存在多态方法.
L2将编译失败,static_cast并不允许两个完全不相干的类互相转换.
dynamic_cast的这种特性,在提取一个对象的某个接口的时候,非常有用,它很类似于实现了COM的QueryInterface的功能。
dynamic_cast 主要用于执行“安全的向下转型(safe downcasting)”,也就是说,要确定一个对象是否是一个继承体系中的一个特定类型。它是唯一不能用旧风格语法执行的强制转型。也是唯一可能有重大运行时代价的强制转型。
reinterpret_cast
。使用这个操作符的类型转换,其的转换结果几乎都是执行期定义(
implementation-defined
)。因此,使用
reinterpret_casts
的代码很难移植。
reinterpret_casts
的最普通的用途就是在函数指针类型之间进行转换。
正是因为新的类型转换符缺乏美感才能使它弥补了在含义精确性和可辨认性上的缺点。使用新类型转换符的程序更容易被解析(不论是对人工还是对于工具程序),它们允许编译器检测出原来不能发现的错误。这些都是放弃
C
风格类型转换方法的强有力的理由。还有第三个理由:也许让类型转换符不美观和键入麻烦是一件好事。
posted on 2006-10-27 16:48
崔少伟 阅读(357)
评论(0) 编辑 收藏 引用 所属分类:
C++