C++ 类型转换

1、static_cast

 静态转化static_cast 全部用于明确定义达到转换,包括编译器允许我们所做的不用强制类型转换的安全转换和不太安全但清楚定义的转换。简单来说等价与c语言的隐式转换。

void main()
{
	int a = 10;
	double d = 12.34;
	a = static_cast<int>(d);  //用于替换C中隐式转换
	//int *p = static_cast<int*>(&d);  //double类型的指针不能隐式转换为int类型的指针
}

2、const_cast

 常量转换const_cast,如果从const转换为非const,或从volatile转换为非volatile,可以直接使用const_cast,这也是唯一允许的转换方法。const_cast只能调节类型限定符,不能改变基础类型

void main()
{
	const int a = 10;
	int *p = const_cast<int*>(&a);  //用于去掉const 和 volatile
	volatile int b = 10;
	int *p1 = const_cast<int*>(&b);
	double d = 12.34;
	//int *p2 = const_cast<int*>(&d);//  不能转换 
}

3、reinterpret_cast

 重解释转换,这是最不安全的转换,reinterpret_cast 把对象假象位模式,是一个完全不同类型的对象,在使用reinterpret_cast 做任何事情之前,实际上总需要reinterpret_cast 转换回原来的类型。C++中的reinterpret_cast 主要是将数据从一种类型的转换位另一种类型。所谓“通常位操作数的位模式提供较低的重新解释”,也就是说将数据以二进制存在形式重新解释。
 以二进制形式重新解释

void main()
{
	double d = 12.34;
	int *p2 = reinterpret_cast<int*>(&d);
	cout << *p2 << endl;//直接输出是   2061584302 
}

这是因为double存储数据是以1 8 13的原则存储,而reinterpret_cast直接取double的8字节中的前4个字节的数据。因此,在使用reinterpret_cast时,是需要再转换完成后重新转换回来.

void main()
{
	double d = 12.34;
	int *p2 = reinterpret_cast<int*>(&d);
	cout << *p2 << endl;//输出   2061584302 
	cout << *(double*)p2 << endl;//输出 12.34	
}

 不安全性:

class A
{
private:
	int m_a = 0;
};
class B
{
private:
	int m_b = 0;
};
class D : public A, public B
{
private:
	int m_c = 0;
};
void main()
{
	D d;
	printf("%p, %p, %p\n", &d,  static_cast<B*>(&d), reinterpret_cast<B*>(&d)); //重解释
}

输出
在这里插入图片描述
d对象内存存储机制如下:
在这里插入图片描述
我们发现,再将d转换为d的父类B的指针后,reinterpret_cast<B*>(&d)的结果仍与&d是相同的,而 static_cast<B*>(&d)是指向真实的B,是正确的。而当B* b =reinterpret_cast<B*>(&d), b=&d时,之后在使用b可能会导致不正确的结果。

4、dynamic_cast

 针对继承体系,主要用于类型安全的向下转化(于将一个父类对象的指针/引用转换为子类对象的指针或引用(动态转换))1.dynamic_cast只能用于含有虚函数的类 2. dynamic_cast会先检查是否能转换成功,能成功则转
换,不能则返回0

class Base
{
public:
	virtual void fun()const
	{
		cout<<"This is Base::fun()"<<endl;
	}
private:
	int m_a = 0;
};
class D : public Base
{
public:
	void fun()const
	{
		cout<<"This is D::fun()"<<endl;
	}
	void show()const
	{
		cout<<"This is D::show()"<<endl;
	}
private:
	int m_c = 0;
};
void Active(Base *pb)
{
	pb->fun();
	//(dynamic_cast<D*>(pb))->show(); //避免
	D *pd = dynamic_cast<D*>(pb);  //用于检查向下转换的合法性
	if(pd != NULL)
		pd->show();
	else
		cout<<"非法的转换...."<<endl;
}
void main()
{
	D d;
	Base b;
	Active(&b);
	
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值