[转]c++中的reinterpret_cast

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_castreinterpret_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_castmData上的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 ( ) ;   
} 

参考文章:
https://www.cnblogs.com/wangsicongde/p/7599288.html

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值