结论
- C++代码中,对于基础类型(int、float、void、enum、指针等)尽量使用
static_cast
进行转换,而不是使用C风格的强制类型转换。 - 继承类之间的转换,尽量不要使用
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
进行类型转换,可以看这篇文章进行了解。编译式类型转换
主要应用场景
- 基本数据类型之间的转换,例如char、int、float、double等,需要自行保证安全性。
- 将void指针转换为任意类型指针。
- 任意类型转换为void类型。
- 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挡不住!