对这几个reinterpret_cast,static_cast,dynamic_cast不太明白,哪位解释一下啊,分全送……
描述:
如在IUnknown::QueryInterface()中
if(iid == IID_IUnknown)
{
*ppi = static_cast<IX *>(this);
}
而在后面
reinterpret_cast<IUnknown *>(*ppi)->AddRef();
另外也请稍带比较dynamic_cast
解决方案1:
static_cast
用于数字之间的转换,如int a = static_cast< int >( 0.5f );等
用于类层次之间的转换,即只能用于从父类指针向子类指针转换,不可不在同一继承层次中的类的指针之间互相转换。
static_cast是静态转换,编译时刻进行转换,并进行正确的对象布局(比如虚函数表的位置)。比如CC派生自CA和CB,而如下:
CC c; CA *pA = static_cast< CA* >( &c );则正确,而
CA *pA = reinterpret_cast< CA* >( &c );不一定正确,要视CC定义时,CA和CB之间的顺序。
假定c对象中,开头8个字节是CB的部分,接着8个字节是CA的部分,最后8个字节是CC自己增加的部分,而用static_cast就会将&c返回的4个字节长度的数加个8,即正确的类型转换(编译时刻完成),但是reinterpret_cast就不会加8。
reinterpret_cast是强制转换,即将被转换的对象看作一个数字(小于等于4字节),不论其是否指针,即可如下:
CC *pC = reinterpret_cast< CC* >( 1.0f );
不会象static_cast那样检测类型,判断两边是否属于同一个继承层次,并进行相应的指针偏移(如上就必须偏移8字节)。
dynamic_cast和static_cast相同,会进行指针的偏移,不过是运行时进行转换,就可检测被转换对象到底是否在同一个继承层次,不是象static_cast那样通过程序员的声明来确定,而是通过被转换对象所带有的运行时期类信息(RTTI)确定,如果不是,将返回null以指出失败。
由于需要RTTI的支持,因此每个对象将会比原来的尺寸多出4个字节用来存放RTTI,将会增加内存的损耗;并且要进行条件判断,速度将会更慢。要支持RTTI,需要开启相应的编译器选项。
一般应不使用dynamic_cast,且不开启RTTI,除非程序必需要用到RTTI进行运行时期信息识别,但这种情况一般都可使用其他方式实现,避开RTTI的使用。
const_cast完全是出于语意的需求,只是简单的将const的变量转成非const或反之,由于是针对语意的,说起来比较麻烦,在此不表。
应该全部使用上诉4个C++提供的转换符,而不要使用C语言风格转换符(对于函数指针则只有用C语言转换符)。使用C语言风格转换符将会统一使用static_cast,即自动的进行指针的偏移,如果不希望进行偏移,还得( ( CA* ) ( (int*) &c ) )。并且编译时,新的转换符意义明确,可以加快编译器的编译(不用去判断是否在同一个继承层次,虽然加快的速度人是不可能感觉得出来的),而且使用新的转换符,程序的可读性增加,并且const_cast的加入更增加了语意的完善。
reinterpret_cast允许任何类型的指针转换到别的任何类型的指针,不太安全一切都要自己小心使用。
#include <iostream>
unsigned short Hash( void *p )
// Returns a hash code based on an address
{
unsigned int val = reinterpret_cast<unsigned int>( p );
return ( unsigned short )( val ^ (val >> 16));
}
using namespace std;
int main()
{
int a[20];
for ( int i = 0; i < 20; i++ )
cout << Hash( a + i ) << endl;
}
static_cast是静态的,没有运行时的类型检查,而dynamic_cast有运行时的类型检查,static_cast不安全,一般少用,用的时候自己必须想清楚是否安全!这两个主要是对对象指针和引用的转换
class B { ... };
class D : public B { ... };
void f(B* pb, D* pd)
{
D* pd2 = static_cast<D*>(pb); // not safe, pb may
// point to just B
B* pb2 = static_cast<B*>(pd); // safe conversion
...
}