[C/C++ 基础](类型转换系列二) static_cast与传统的C风格强制类型转换

结论

  1. C++代码中,对于基础类型(int、float、void、enum、指针等)尽量使用static_cast进行转换,而不是使用C风格的强制类型转换。
  2. 继承类之间的转换,尽量不要使用static_cast而是使用dynamic_cast,因为缺乏足够的安全性。

static_cast

通常的使用形式是:

new_type b = static_cast < new_type > ( expression );

static_cast与C风格的强制类型转换类似,但是限制性更加的强,相对来说也更加的安全。

与C风格强制类型转换的区别

两者的主要区别在于,static_cast具有编译时检查的功能,C风格类型转换没有。因此前者在编译期间就可以帮你把错误找出,而后者会在程序运行期间产生错误。弄清两者的区别可以让我们更好的理解使用static_cast的好处。
static_cast将允许编译器检查指针和被指向的数据类型是否兼容,这允许程序员在编译期间捕获这种不正确的指针分配。
举个简答的例子进行说明:

char c = 1;
char *pc = &c;

//C风格类型转换
int *pi = (int*)pc;
*pi = 5;             //内存越界分配,可能导致内存覆写,造成运行期间crash

//static_cast类型转换
int *pi_2 = static_cast<int*>(pc);  //编译错误,不允许这种操作。

在代码中已经说明原因,如果你坚持这种转换方式,你需要使用reinterpret_cast进行类型转换,可以看这篇文章进行了解。编译式类型转换

主要应用场景

  1. 基本数据类型之间的转换,例如char、int、float、double等,需要自行保证安全性。
  2. 将void指针转换为任意类型指针。
  3. 任意类型转换为void类型。
  4. enum class与数值类型之间的转换。

简单的事例

在下面的情境下我们来讨论这个问题,老王有一个儿子小明,老王有10块钱,准备留给小明继承。
小明自己有11块,所以小明总共16块钱;

#pragma once
#include<iostream>

//父亲:老王
class LaoWang
{
public:
	LaoWang() :m_LaoWangMoney(10) {}
	~LaoWang() {}

	virtual void money() {
		std::cout << m_LaoWangMoney<< std::endl;
	}
	void laowang_money() {
		std::cout << m_LaoWangMoney<< std::endl;
	}
	int m_LaoWangMoney;

};

//儿子,小明
class XiaoMing:public LaoWang
{
public:
	XiaoMing() :m_XiaoMingMoney(11) {}
	~XiaoMing() {}
	void money() override {
		std::cout << m_LaoWangMoney / 2 + m_XiaoMingMoney << std::endl;
	}
	void xiaoming_money() {
		std::cout << m_XiaoMingMoney<< std::endl;
	}

private:
	int m_XiaoMingMoney;
};

基础类型之间的变换

简单的举个例子:老王买水果,水果值5.9元,老王讨价还价后,商家同意把零头抹掉。

LaoWang lao_wang();
float fruits = 5.9;
lao_wang.m_LaoWangMoney -= static_cast<int>(fruits);

基础类型的转换上,与C风格的类型转换一致。

继承类之间的变换

例如:小明长大了变成了老王2号,并且继承了老王的钱;但是由于不能返老还童,老王不能变成小明2号

LaoWang* lao_wang = new LaoWang();
XiaoMing* xiao_ming = new XiaoMing();

//子类转基类,正确!
LaoWang* lao_wang_2 = static_cast<LaoWang*>(xiao_ming);
lao_wang_2->laowang_money();

//基类转子类,访问错误内存!
XiaoMing* xiao_ming_2 = static_cast<XiaoMing*>(lao_wang);
xiao_ming_2->xiaoming_money();

在这个例子中,编译也不会报错,程序也不会crash。子类转基类(小明变老王)完全正确,但是基类转子类(老王变小明)中,程序正常运行,但是会访问到了错误内存,这是一个更加难以查找到的错误。因此非常不安全。

强调

再C++代码中,尽量使用static_cast代替C风格的强制类型转换,提高程序的安全性。
在这里插入图片描述
点赞收藏加关注,乱杀Bug挡不住!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值