C++ 强制类型转换

const_cast

const_cast用于修改类型的const、volatile属性。
const_cast<?>(?), <>中必须是指针、引用或者右值 - (the type in a const_cast must be a pointer, reference, or pointer to member to an object type)。

class B
{
public:
	int _m;
	B() :_m(100){};
};

int test_cast()
{
	const B b1;
	B* b2 = const_cast<B*>(&b1);
	b2->_m = 1;
	cout << &(b1._m) << endl;
	cout << &b2->_m << endl;
	cout << b1._m << endl;
	cout << b2->_m << endl;

	const int i = 100;
	int* ii = const_cast<int*>(&i);
	*ii = 1;
	cout << &i << endl;
	cout << ii << endl;
	cout << i << endl;
	cout << *ii << endl;
	return 0;
}

output:

addr of b1._m:  0000005A90EFF8D0
addr of b2._m:  0000005A90EFF8D0
value of b1._m: 1
value of b2._m: 1

addr of i:   0000005A90EFF8D4
addr of ii:  0000005A90EFF8D4
value of i:  100
value of ii: 1

可以通过const_cast修改const B b1中的成员变量的值。但要注意的是const int通过const_cast修改值之后,很神奇的,原值i和修改值ii的地址是一样的,但是其值是不一样的。

reinterpret_cast

强制类型转换符,任意转换,使用需谨慎。
用于进行各种不同类型的指针之间、不同类型的引用之间以及指针和能容纳指针的整数类型之间的转换。转换时,执行的是逐个比特复制的操作。

	int *n = new int;
	double *d = reinterpret_cast<double*>(n);

有意义的用法是hash函数中。

// 将地址转化为hash值
unsigned short Hash( void *p ) {
   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把一个表达式转换为某种类型,但没有运行时类型检查来保证转换的安全性。不能用于在不同类型的指针之间互相转换,也不能用于整型和指针之间的互相转换,当然也不能用于不同类型的引用之间的转换;能用于整型和浮点型、字符型之间的互相转换,以及类的上行转换

	double n = 100.092;
	int d = static_cast<int>(n);  // d=100
	// error
	int *d = static_cast<int*>(&n);

dynamic_cast将一个基类对象指针(或引用)转换到继承类指针,与static_cast不同的是dynamic_cast会根据基类指针是否真正指向继承类指针来做相应处理。
dynamic_cast<?>(?), <>中必须是指针、引用或者void *- (the type in a dynamic_cast must be a pointer or reference to a complete class type, or void *)

class B
{
public:
	int m_iNum;
	virtual void foo();
};
 
class D : public B
{
public:
	char *m_szName[100];
};
 
void func(B* pb)
{
	D* pd1=static_cast<D*>(pb);
	D* pd2=dynamic_cast<D*>(pb);
}

上行转换时安全的,即D->B。如果pb是D类型,则pd1和pd2是一样的,且都可以安全执行操作;
下行转换,即B->D会出现问题,static_cast的问题是转换后的pd1是一个B类型的指针,若有对m_szName的操作则会出现问题;而dynamic_cast将会返回空指针,即pd2为空指针,因为pd2本身是从B转换而来,无法变为D,所以可以尽早防止error产生。
另外要注意:B 要有虚函数,否则会编译出错;static_cast则没有这个限制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值