C风格的强转:
隐式转换(编译器自动转换)
会出现警告,精度丢失
代码:
#include <iostream> using namespace std; int main(int argc, char* argv[]) { char cc = 'X'; float ff = cc; // 隐式转换,不会告警。 double dd = 3.38; long ll = dd; // 隐式转换,会告警。。 }
输出:
强制类型转换
不会出现警告,精度丢失一样存在
代码:
#include <iostream> using namespace std; int main(int argc, char* argv[]) { char cc = 'X'; float ffc = static_cast<float>(cc); // 显式地使用static_cast进行强制类型转换,不会告警。 double dd = 3.38; long llc = static_cast<long>(dd); // 显式地使用static_cast进行强制类型转换,不会告警。 int a = int(dd); }
输出:
C++风格的强转:
C++强制类型转换
C风格的强制类型转换很容易理解,不管什么类型都可以直接进行转换,使用格式如下:
目标类型 b = (目标类型) a;
C++也是支持C风格的强制类型转换,但是C风格的强制类型转换可能会带来一些隐患,出现一些难以察觉的问题,所以C++又推出了四种新的强制类型转换来替代C风格的强制类型转换,降低使用风险。
在C++中,新增了四个关键字static_cast、const_cast、reinterpret_cast和dynamic_cast,用于支持C++风格的强制类型转换。
C++风格的强制类型转换能更清晰的表明它们要干什么,程序员只要看一眼这样的代码,立即能知道强制转换的目的,并且,在多态场景也只能使用C++风格的强制类型转换。
一、static_cast
static_cast是最常用的C++风格的强制类型转换,主要是为了执行那些较为合理的强制类型转换,使用格式如下:
static_cast<目标类型>(表达式);
用于基本内置数据类型之间的转换
C风格:编译器可能会提示警告信息。
static_cast:不会提示警告信息。
#include <iostream> using namespace std; int main(int argc, char* argv[]) { char cc = 'X'; float ff = cc; // 隐式转换,不会告警。 float ffc = static_cast<float>(cc); // 显式地使用static_cast进行强制类型转换,不会告警。 double dd = 3.38; long ll = dd; // 隐式转换,会告警。 long llc = static_cast<long>(dd); // 显式地使用static_cast进行强制类型转换,不会告警。 }
用于指针之间的转换
C风格:可用于各种类型指针之间的转换。
static_cast:各种类型指针之间的不允许转换,必须借助void*类型作为中间介质。
#include <iostream> using namespace std; int main(int argc, char* argv[]) { int type_int = 10; float* float_ptr1 = (float*)&type_int; //C风格直接强转 cout << "C风格" << "*float_ptr1 = " << *float_ptr1 << endl; // float* char_ptr2 = static_cast<float*>(&type_int); // int* -> char* 使用static_cast转换无效 void* void_ptr = &type_int; // 任何指针都可以隐式转换为void* float* float_ptr4 = static_cast<float*>(void_ptr); // void* -> float* 使用static_cast转换成功 cout << "C++风格" << "*float_ptr4 = " << *float_ptr4 << endl; }
转换之后的数据是不精确的
不能转换掉expression的const或volitale属性
#include <iostream> int main(int argc, char* argv[]) { int temp = 10; const int* a_const_ptr = &temp; int* b_const_ptr = static_cast<int*>(a_const_ptr); // const int* -> int* 无效 const int a_const_ref = 10; int& b_const_ref = static_cast<int&>(a_const_ref); // const int& -> int& 无效 volatile int* a_vol_ptr = &temp; int* b_vol_ptr = static_cast<int*>(a_vol_ptr); // volatile int* -> int* 无效 volatile int a_vol_ref = 10; int& b_vol_ref = static_cast<int&>(a_vol_ref); // volatile int& -> int& 无效 }
C++与C强转异同(下)https://developer.aliyun.com/article/1429076