在C中进行强制类型转换,直接()就可以了。在c++中,提供了四种类型转换,static_cast、dynamic_cast、 reinterp_cast、const_cast。当然,如果你要用()强转也行,c++是兼容c的。关于这四种转换,网上有介绍很仔细很详细的。我这 里只想简单的介绍其常用的规则。这些东西大多都用在转换指针上。
static_cast
快速的类型转换,如果可以转换则一定会成功。代价是被转换的类型可能不是正确的类型,后面调用就会有可能出错。什么叫“可以转换”?就是有一条确定的转换路径。如果不可以,会编译出错的。
用法: static_cast < type-id > ( expression )
常常用于下面几种情况:
用于类层次结构中基类和子类之间指针或引用的转换。进行上行转换(把子类的指针或引用转换成基类表示)是安全的;进行下行转换(把基类指针或引用转换成子类指针或引用)时,由于没有动态类型检查,所以是不安全的。 用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。 把 void指针转换成目标类型的指针(不安全!!) 把任何类型的表达式转换成void类型。 dynamic_cast检查类型的安全的转换, 无法完成的转换会返回NULL(转换指针)或者抛出异常(转换引用). 效率较低。比如把父类对象指针转换成子类指针就会返回NULL。有这样的特性,有时候我们可以利用它来判断某个指针指向的对象是哪个对象。
reinterp_cast简单的转换,万能的转换。也是危险的,程序员得自己保证它的安全。
const_cast用来修改类型的const或volatile属性。
例如:
C++代码
class A { };
用法: static_cast < type-id > ( expression )
常常用于下面几种情况:
用于类层次结构中基类和子类之间指针或引用的转换。进行上行转换(把子类的指针或引用转换成基类表示)是安全的;进行下行转换(把基类指针或引用转换成子类指针或引用)时,由于没有动态类型检查,所以是不安全的。 用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。 把 void指针转换成目标类型的指针(不安全!!) 把任何类型的表达式转换成void类型。 dynamic_cast检查类型的安全的转换, 无法完成的转换会返回NULL(转换指针)或者抛出异常(转换引用). 效率较低。比如把父类对象指针转换成子类指针就会返回NULL。有这样的特性,有时候我们可以利用它来判断某个指针指向的对象是哪个对象。
reinterp_cast简单的转换,万能的转换。也是危险的,程序员得自己保证它的安全。
const_cast用来修改类型的const或volatile属性。
例如:
C++代码
class A { };
class B : public A { };
class C { };
class D : public A { };
class E : public D, public B { ... };
A* pa = new B(); // pa 实际指向一个B对象
B* pb = dynamic_cast<B*>(pa); // 转换成 B对象指针, 这里会成功,因为 pa实际指向一个B对象
pb = static_cast<B*>(pa); // 成功,因为A和B之间有明确的继承关系
delete pa;
pa = new A(); // 现在pa 指向一个A对象
pb = dynamic_cast<B*>(pa); // 不成功,返回0, 因为pa不是指向一个B对象
pb = static_cast<B*>(pa); // 成功, 同上,但是这个pb指针在这里使用可能会出问题(并不是一定会出)
C* pc = static_cast<C*>(pa); // 这里编译就会出错.因为C*和A*之间没什么连系, 编译器不知道怎么转换 C* pc = reinterp_cast<C*>(pa); // 成功, 类型是转过来了,指针还是指向一个A对象(危险!!)
// 下面看看向上转型,这里有多继承.
E* pe = new E(); A* pa2 = dynamic_cast<A*>(pd); // 编译错误! 因为E包含A从两条不同的路径
A* pa3 = static_cast<A*>(pd); // 同上
A* pa4 = static_cast<A*>(static_cast<B*>(pd)); // 可以,通常这里会对指针值做调整.因为第二个基类的起点在派生类里可能会有变化
A* pa5 = reinterp_cast<A*>(pd); // 可以, 但这里不会调整指针值(危险!!)
class Base { }
class Derive1 :public Base { }
class Derive2 :public Base { }
void fun(Base *p)//如果这里p只有两种可能Derive1和Dervie2
{ Derive1 *p1=dynamic_cast<Dervie1*>(p);
if(p!=NULL) {//p指向的是 Dervie1的对象 }
else {//p指向的是Dervie2的对象 } }
class Test { public: int n; }
const Test *c=new Test(); c->n=4;//编译出错
Test *d=const_cast<Test*>(c); d->n=3;//OK