转自:http://blog.sina.com.cn/s/blog_499386b00100dvvp.html
注:文中的一些链接已经不可访问,另,修正原文中的一段乱码,参考MSDN http://msdn.microsoft.com/zh-cn/library/vstudio/cby9kycs.aspx。
static_cast: includes no run-time checking, so is fast and potentially dangerous.
dynamic_cast: includes run-time checking, so is slow and safe. Returns a null pointer if the cast fails.
safe_cast: same as dynamic cast, but throws an exception if the cast fails.
以上引自:http://blog.csdn.net/xeonol/archive/2008/07/17/2667519.aspx
抛出异常毕竟是不错的,还是用safe_cast吧。
程序静态期(static-time)
msdn上的解释是:safe_cast
One example of where the compiler will not accept a static_cast but will accept a safe_cast is for casts between unrelated interface types. With safe_cast, the compiler will not issue a conversion error and will perform a check at runtime to see if the cast is possible
// compile with: /clr
using namespace System;
interface class I2 {};
interface class I3 {};
}
另外仔细看看:http://topic.csdn.net/t/20060820/08/4961965.html
还有这个http://hi.baidu.com/baiyw920/blog/item/6876db0f4c31f2e037d1224b
dynamic_cast:
用法:dynamic_cast < type-id > ( expression )
1.如果type-id是一个类指针,并且指向的类是expression的基类或间接基类,则dynamic_cast返回结果是指向type-id类的指针,该指针所指的对象是expression的部分对象。此类转换被称之为“向上映射”,因为它只是在类继承层次中向上移动指针,从子类到基类。向上映射”是一种隐式转换。
2.如果type-id是void*,则会进行运行时检查以确定expression的实际类型。返回结果是一个指向expression所指向的完整对象的指针。
3.如果type-id不是void*,则会进行运行时检查以确定expression所指向的对象是否能转换成type-id所指向的类型。
4.如果expression类型是type-id类型的基类,则进行运行时检查以确定expression是否实际指向了type-id类型的完整对象。如果的确如此,则返回结果是一个指向一个完整对象的type-id类型的指针。此类转换称之为“向下映射”,因为它在类继承层次中向下移动指针,从基类到子类。在多重继承中,会存在二义性。
5.支持交叉映射。当然在两个毫无关联的类之间进行交叉映射一般不会成功的,交叉映射一般出现在多继承中。例如:类B和类C是两个独立的类,类E同时继承了B和C。
B* pb = new E;
C* pc = dynamic_cast<C*>(pb);
上述交叉转换会成功,因为pb虽然是B类型的,但它指向E类型的完整对象,E又同时继承了B和C,所以E中也包括到了C的完整数据,所以可以实现到C类型的转换。
6.支持null值的指针转换成null值的另外类型的指针。这是交叉映射的特殊情况。一般情况下,两个毫无关联的类型之间的交叉转换不会成功,但如果要转换的值是null的话,则可以实现两种类型的指针之间的转换。
异常处理:
1.当使用dynamic_cast时,如果指定的转换不能安全进行,则会在运行时出现转换失败。如果进行的是指针类型的转换,则返回null指针;如果是引用类型的转换,则抛出bad_cast异常。
2.如果参数expression本身就没有指向一个有效的对象,则会抛出__non_rtti_object异常。
static_cast:
用法:static_cast <type-id> ( expression )
1.static_cast常用来进行简单数据类型间的转换而不进行类之间的转换。
2.static_cast也可用来进行任何隐式转换,包括标准转换和用户自定义的转换。
3.支持null值的指针转换成null值的另外类型的指针。
4.任何类型的expression都可显示的转换成void类型,并且转换后的void类型可任意增加const,volatile或__unaligned属性。
5.static_cast仅用于对性能要求很高,而且程序员对转换过程很清楚能保证安全转换的情况下。
6.如果要求在最后的release版本中必须使用static_cast时,那么在debug模式下用safe_cast代替它以保证成功编译。
const_cast:
用法:const_cast < type-id > ( expression )
1.不可使用const_cast操作符直接去除一个const变量的const属性。
2.支持null值的指针转换成null值的目标类型的指针。
// compile with: /EHsc
#include <iostream>
using namespace std;
class CCTest {
public:
private:
};
void CCTest::setNumber( int num ) { number = num; }
void CCTest::printNumber() const {
}
int main() {
}
reinterpret_cast:
用法:reinterpret_cast < type-id > ( expression )
1.reinterpret_cast操作符可用来从char*映射为int*,或从一种类类型指针映射到另一种毫无关联的类类型指针,但这种映射是不安全的。
2.reinterpret_cast操作符映射的结果只有将一种类型映射回它的原始类型的情况下才是安全的,其它映射在最好的情况下也是不可移植的。
3.reinterpret_cast操作符不能将const,volatile或__unaligned映射掉。
4.支持null值的指针转换成null值的目标类型的指针。
5.reinterpret_cast操作符经常用于hash函数中,如下例:
// compile with: /EHsc
#include <iostream>
// 返回一个与地址有关的hash码
unsigned short Hash( void *p ) {
}
using namespace std;
int main() {
}
safe_cast:
用法:[cli]::safe_cast < type-id > ( expression )
1.和static_cast一样,safe_cast调用用户定义的转换。
2.safe_cast不使用const_cast(映射掉const)。
3.safe_cast存在于cli名字空间中。
4.在两个不相关的接口类型间进行映射的情况下,编译器只接受safe_cast而不接受static_cast。使用safe_cast的时候,编译器不产生转换错误,而是在运行时进行检查判断转换是否可能进行。
// compile with: /clr
using namespace System;
interface class I1 {};
interface class I2 {};
interface class I3 {};
ref class X : public I1, public I2 {};
int main() {
}