C++--类型转换(Type Casting)
dynamic_cast
dynamic_case仅能用于对象的指针或引用。如果转换失败,则返回0
1. 将子类转成父类。
class CBase { };
class CDerived: public CBase { };
CBase* pb;
CDerived d;
pb = dynamic_cast<CBase*>(&d); // 正确:将子类转成父类
2. 将父类转换成子类,必须满足下面两个条件。
2.1 要求父类必须是多态类型(polymorphic type)的类,即要有虚函数。
class CBase { virtual void dummy() {} };
class CDerived: public CBase { int a; };
CBase * pba = new CDerived; // 指向子类对象的父类指针
CBase * pbb = new CBase; // 指向父类对象的父类指针
CDerived * pd;
pd = dynamic_cast<CDerived*>(pba); // 正确:将多态的父类转换成子类
pd = dynamic_cast<CDerived*>(pbb); // 语法正确,但是pd的值为0
2.2 要求被转换的指针指向的是完整对象(complete object),这样才能得到转换后的正确值。
比如上面的pbb是指向父类CBase对象的,而转换目标是CDerived,故不是指向一个完整对象,因而转换后的pd为0。指针转换失败,得到的值是0;如果是引用转换失败,则会抛出bad_cast异常。
CBase b;
try
{
CDerived &d = dynamic_cast<CDerived&>(b);
}
catch (bad_cast)
{
// handle the fact that the cast failed
}
3. 可以将任何类型的指针转成空指针(void*)
static_cast
1. 可以进行各种基本类型的转换
double d=3.14159265; int i = static_cast<int>(d);
2. 进行指针转换,类必须是有关联(继承和被继承关系)的。既可以把子类转成父类,也可以把父类转成子类。不做安全检查。需要程序员自己确保转换的安全性。所以里建议使用dynamic_cast。
class CBase {};
class CDerived: public CBase {};
CBase * a = new CBase;
CDerived * b = static_cast<CDerived*>(a); // 语法正确,且b不为0
由于不做安全检查,这里的b虽然不为0,但是下面如果调用子类的方法,就会出错。
reinterpret_cast
1. 可以进行指针和整形直接的互转。如果将指针转成整形,必须确保整形足够放的下指针的值。
class A {};
A *a = reinterpret_cast<A*>(0x40000000);
2. 将任何指针进行转换,甚至类可以是无关联的。它所做的就是简单地将一个指针值复制给另一个指针。
class A {};
class B {};
A * a = new A;
B * b = reinterpret_cast<B*>(a);
const_cast
去除变量的const属性。
const char * cc = "sample text";
char *c = const_cast<char*>(cc);
参考资料
http://www.cplusplus.com/doc/tutorial/typecasting/