C/C++的类型转换
类型转换在C语言就存在,在C语言中,存在两种类型转换,一种是隐式类型转换,通常发生在具有关联的类型之间,另一种则是显式类型转换,通过()运算符完成。
在C++中,加入了类后,C语言的内置类型也可以和自定义类型进行隐式类型转换,前提是提供相应的构造函数。
C++11后,有了一些接口,可以让C++的类型转换更加合理,可读性更高。
C++11后新增转换接口
static_cast
static_cast类型转换,主要体现在static(静态)上,及代表其转换完成的是在编译阶段,该接口可以完成大部分C语言的强制类型转换,以及C++语言中的类之间的转换,但其不会对转换是否危险做出判断。
但是它不能去除变量的某些属性,如const,volatile等等。
其能进行的一些常见转换如下
1).内置类型之间
如char - int , double - int , int - double …
2).内置指针类型之间
只能将void*类型的指针转换为其他类型,不能在其他固定类型之间进行转换。
3).自定义类型的指针/引用
static_cast可以对继承类之间进行转换,但是从指向父类对象的父类指针 ---- 子类指针转换可能会出现安全问题,但是static_cast,不进行检测,所有有可能访问到脏数据。
4).引用之间转换
static_cast可以在引用之间进行转换,可以将左值 ---- 右值之间进行转换,比如move接口的实现。
template<typename _Tp>
inline typename std::remove_reference<_Tp>::type&&
move(_Tp&& __t)
{ return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); }
dynamic_cast
dynamic_cast类型转换,同样故名思意,及代表其转换完成不止是在编译阶段,在运行阶段,同样会进行检测转换是否危险,同时dynamic_cast只能完成继承体系中的指针/引用类型之间的转换,同时需要继承体系类中父类要存在虚函数。
1).继承体系中,指针/引用之间转换。
测试类如下:
对指针进行转换,存在安全问题,返回空。
对引用进行转换,转换存在安全问题,不会返回空,会报错std::bad_cast。
const_cast
const_cast类型转换,主要用于去除指针/引用的常量性,因此,其也是只能对指针/引用进行转换。
1).不能去除非指针/引用的常量性
2).去除指针/引用的常量性
3).如果去除被const修饰的变量的指针的常量性,则可能出现如下现象。
地址相同,但是值不同,这是因为被const修饰的值会在编译阶段直接被替换
可以使用volatile声明变量和指针,防止这种现象。
const_cast去除指针的常量性,并不是一件好事,建议不要使用。
reinterpret_cast
reinterpret_cast类型转换,故名思意为重新解读,它可以让指针和指针之间进行转换,以及指针和变量之间转换,是无关类型之间进行转换,其是对比特位的简单拷贝和重新理解。
1).变量与指针,指针与指针
2).自定义类型之间,不能进行强制类型转换