C++中的类型转换 static_cast、dynamic_cast、const_cast、reinterpret_cast

类型转换可以让我们将一种类型的变量当做另外一种类型来使用,常见的类型转换方式包括

C风格的类型转换

转换格式为:(类型)变量

int a = 10;
double b = a;
float c = b;
Base* base = (Base*)new Derived();

C++自带的类型转换

  • static_cast
  • dynamic_cast
  • const_cast
  • reinterpret_cast

为什么有了C风格的类型转换方式后C++还添加这四种类型转换方式呢?

因为C风格的类型转换可以在任意类型之间转换,比如你可以把一个指向const对象的指针转换成指向非const对象的指针,把一个指向基类对象的指针转换成指向一个派生类对象的指针,这两种转换之间的差别是巨大的,但是传统的c语言风格的类型转换没有区分这些。还有一个缺点就是,c风格的转换不容易查找,他由一个括号加上一个标识符组成,而这样的东西在c++程序里一大堆。

static_cast

类似与C风格的无条件静态类型转换

1、基类和子类之间的转换,其中:子类->基类是安全的,但是基类->子类是不安全的,建议使用dynamic_cast进行运行时判断进行基类转子类。

2、基本数据类型之间的转换,int, char, float,注意不可以进行无关类型指针的转换。

3、转换空指针为任何类型的空指针

Base* base1 = static_cast<Base*>(new Derived());	
Derived* base2 = static_cast<Derived*>(new Base());	 //基类->子类,有风险,不推荐使用

double num = static_cast<double>('a');	//char->double
// double* ptr = static_cast<double*>(new int(10));	错误,无关类型的指针转换,转换无效
	
double* ptr = static_cast<double*>(nullptr);	//空指针->任意类型的空指针

dynamic_cast

动态转换主要是用于类的层次间、基类子类间转换,具有检验功能,在无法进行转换时返回nullptr。如果转换的是引用,失败时会抛出std::base_cast异常。可以通过返回值进行判断是否成功转换。

Base* base = dynamic_cast<Base*>(new Derived());		//成功
if (base == nullptr) {
	std::cout << "derived -> base 失败" << std::endl;
}

Derived* derived = dynamic_cast<Derived*>(new Base());	 //失败
if (derived == nullptr) {
	std::cout << "base -> derived 失败" << std::endl;
}

返回失败

const_cast

用于移除、添加变量的const属性,注意C++中其他的三类转换都没有移除const属性的能力,对于const_cast主要用来对顶层、底层的const进行转换。为什么不可以对变量的const进行修改呢?因为没有意义。

int i = 10;
const int* p = &i;
const int* ci = const_cast<const int*>(p);
//*ci = 20; 提示错误,表达式必须是可修改的左值
int* c = const_cast<int*>(p);
*c = 20;

reinterpret_cast

re重新的意思,interpret解读、翻译的意思,顾名思义将数据重新按照另外一种类型进行解读,一般很少用到,不清楚自己在操作什么数据时,请谨慎使用。比如将四个字符当做当做一个浮点数进行处理。

char ch[4] = { 'a', 'b', 'c', 'd' };
float* f = reinterpret_cast<float*>(ch);	//四个字符共四个字节正好当做一个浮点数来处理(不严谨,具体根据各个平台浮点数字节大小可能不一样)

std::cout << *f << std::endl;

输出

 本质上C++中的四种类型转换都是语法糖,所有能做的C风格转换也可以做到。但是使用C++中的类型转换,可以让我们更好的追踪到我们的项目里面的哪里有用到类型转换,这是C风格转换所不具有的优势的。

更多参考:

https://stackoverflow.com/questions/332030/when-should-static-cast-dynamic-cast-const-cast-and-reinterpret-cast-be-used

 

posted @ 2020-11-19 21:34  xnuwu  阅读(769)  评论(1编辑  收藏  举报