reinterpret_cast含义
reinterpret
意为“重新解释”,它是C++中与C风格类型转换最接近的类型转换运算符。它让程序员能够将一种对象类型转换为另一种,不管它们是否相关。
reinterpret_cast
用在任意指针(或引用)类型之间的转换;以及指针与足够大的整数类型之间的转换; 从整数类型(包括枚举类型)到指针类型,无视大小。
(所谓"足够大的整数类型",取决于操作系统的参数,如果是32位的操作系统,就需要整形(int)以上的;如果是64位的操作系统,则至少需要长整形(long)。具体大小可以通过sizeof运算符来查看)。
【注意】
reinterpret_cast
不能用于内置类型
之间的转换,只能用于不同指针
之间的转换。
CBase* pBase = new CBase( ) ;
CDerived* pDerived = reinterpret_cast<CDerived*>(pBase) ;
这种类型转换实际上是强制编译器接受static_cast
通常不允许的类型转换,它并没有改变指针值的二进制表示,只是改变了编译器对源对象的解释方式。
应尽量避免使用reinterpret_cast
reinterpret_cast VS static_cast
- static_cast主要管:有继承关系类的指针和内置数据类型的转换(和C的内置类型转换规则一致,可能改变底层的位,也可能不改变)。
- reinterpret_cast主要管:所有指针(引用)之间的转换
在它们管理的交叉点处——有继承关系的指针的转换,处理方式有所不同。
static_cast
和reinterpret_cast
的区别主要在于多重继承
class A
{
public:
int m_a;
};
class B
{
public:
int m_b;
};
class C : public A, public B {};
C c;
printf("%p, %p, %p", &c, reinterpret_cast<B*>(&c), static_cast <B*>(&c));
前两个的输出值是相同的,最后一个则会在原基础上偏移4个字节。
这是因为static_cast
计算了父子类指针转换的偏移量,并将之转换到正确的地址(c
里面有m_a
,m_b
,转换为B*
指针后指到m_b
处),而reinterpret_cast
却不会做这一层转换。
reinterpret_cast VS const_cast
reinterpret_cast
不能像const_cast
那样去除const
修饰符。
int main()
{
typedef void (*FunctionPointer)(int);
int value = 21;
const int* pointer = &value;
int * pointer_r = reinterpret_cast<int*> (pointer); //编译报错
FunctionPointer funcP = reinterpret_cast<FunctionPointer> (pointer);
}
reinterpret_cast
只能改变指针(或引用)的解释方式,不能把其上的const
锁转换掉。const_cast
让程序员能够关闭对象的访问修饰符const。
在理想的情况下,程序员将经常在正确的地方使用关键字const
,但是现实世界,经常可以看到该使用const
的地方没有使用。这样,在外部函数中调用类中的这些成员函数,可能会报错。
CSomeClass
{
public:
….
void DisplayMember( ) ;
};
void DisplayAllData( const CSomeClass& mData )
{
mData.DisplayMembers ( ) ; //编译报错
}
为什么会编译报错?
因为DisplayMembers
为普通的成员函数,故DisplayMembers
成员函数中隐藏的this
指针,会被编译器设置为CSomeClass* this
。而mData
是被const
修饰的,mData.DisplayMembers ( )
;即是DisplayMembers ( &mData);
这样,实参和形参类型不一致,编译器会报错。
如何修改这一问题?
1.把函数列表上mData
前的const
去掉。
这样,使代码的安全性降低,其后的代码可能会修改mData
中的值。
2.在成员函数DisplayMembers
前添上const
。
这样固然最好,但是如果CSomeClass
是第三方的类,我们没有其源代码,那怎么办?
3.使用const_cast
把mData
上的const
锁暂时去掉。
void DisplayAllData( const CSomeClass& mData )
{
CSomeClass& refData = const_cast< CSomeClass &>(mData) ;
refData.DisplayMembers ( ) ;
}
另外:const_cast
也可用于指针。
void DisplayAllData( const CSomeClass* pData )
{
CSomeClass* pCastedData = const_cast< CSomeClass *>( pData) ;
pCastedData ->DisplayMembers ( ) ;
}