【C++】C++之类型转换
作者:李春港
出处:https://www.cnblogs.com/lcgbk/p/14209848.html
一、前言
在C语言中,我们经常会对数据进行类型转换,但都是强制性的类型装换,自然就会引发访问不安全的问题,可能不经意间将指向const对象的指针转换成非const对象的指针,可能将基类对象指针转成了派生类对象的指针,这种转换很容易出bug,需要严格审查代码才能消除这种隐患,而且这种转换方式不利于我们审查代码,且程序运行时也可能会出bug,所以C++为了提高类型装换的安全性,关于类型转换引入了四种方式:static_cast、const_cast、dynamic_cast、reinterpret_cast,接下来看下其四种类型装换的应用场景。
二、static_cast
2.1 使用场景
基本数据类型之间的转换使用,例如float转int,int转char等,在有类型指针和void*之间转换使用,子类对象指针转换成父类对象指针也可以使用static_cast。
非多态类型转换一般都使用static_cast,而且最好把所有的隐式类型转换都是用static_cast进行显示替换,不能使用static_cast在有类型指针之间进行类型转换。
2.2 实例
#include <iostream>
using namespace std;
struct Base {
virtual void Func() { cout << "Base Func \n"; }
};
struct Derive : public Base {
void Func() override { cout << "Derive Func \n"; }
};
int main()
{
float f = 1.23;
cout << "f " << f << endl;
int i = static_cast<int>(f);
cout << "i " << i << endl;
void *p;
int *i_p = static_cast<int *>(p);
void *pi = static_cast<void *>(&f);
int *pi = static_cast<int *>(&f); // error invalid static_cast from type ‘float*’ to type ‘int*’
Derive d;
d.Func();
Base *b = static_cast<Base *>(&d);
b->Func();
return 0;
}
三、dynamic_cast
3.1 使用场景
用于将父类的指针或引用转换为子类的指针或引用,此场景下父类必须要有虚函数(只要拥有虚函数就行),因为dynamic_cast是运行时检查,检查需要运行时信息RTTI.如果不清楚什么是RTTI,可以去了解下C++的RTTI机制。
3.2 实例
#include <iostream>
using namespace std;
struct Base {
virtual void Func() { cout << "Base Func \n"; }
};
struct Derive : public Base {
void Func() override { cout << "Derive Func \n"; }
};
int main() {
Derive d;
d.Func();
Base *b = dynamic_cast<Base *>(&d);
b->Func();
Derive *dd = dynamic_cast<Derive *>(b);
dd->Func();
return 0;
}
四、const_cast
4.1 使用场景
用于常量指针或引用与非常量指针或引用之间的转换,只有const_cast才可以对常量进行操作,一般都是用它来去除常量性,去除常量性是危险操作,还是要谨慎操作。
4.2 实例
int main() {
int data = 10;
const int *cpi = &data;
int *pi = const_cast<int *>(cpi);
const int *cpii = const_cast<const int *>(pi);
return 0;
}
五、reinterpret_cast
5.1 使用场景
没啥场景,类似C语言中的强制类型转换,什么都可以转,万不得已不要使用,一般前三种转换方式不能解决问题了使用这种强制类型转换方式。
5.2 实例
int main() {
int data = 10;
int *pi = &data;
float *fpi = reinterpret_cast<float *>(pi);
return 0;
}
六、总结
方式 | 使用场景 |
---|---|
static_cast | 基本数据类型之间的转换使用,例如float转int,int转char等;子类对象指针转换成父类对象指针也可以使用static_cast;在有类型指针和void*之间转换使用,不能使用static_cast在有类型指针之间进行类型转换。 |
dynamic_cast | 用于将父类的指针或引用转换为子类的指针或引用,此场景下父类必须要有虚函数(只要拥有虚函数就行) |
const_cast | 用于常量指针或引用与非常量指针或引用之间的转换。 |
reinterpret_cast | 类似C语言中的强制类型转换,什么都可以转,尽量不要使用此方式。 |