C++类型转换
C语言中的类型转换
隐式类型转换
隐式类型转换(意义相近的类型)
1 | int i = 1; |
显示类型转换
显示的强制类型转换(意义不相近的类型,值转换后有意义)
1 | int main() |
C++强制类型转换
c++也支持c的类型转换,但是c++为了加强类型转换的可视性,引入了四种命名的强制类型转换操作符
static_cast
这个就像c中的隐式类型转换,只不过显示的写了出来,static_cast用于非多态类型的转换(静态转换),编译器隐式执行的任何类型转换都可用static_cast,但它不能用于两个不相关的类型进行转换
1 | int main() |
reinterpret_cast
类似于c的显示强制类型的转换,一般用于将一种类型转换为另一种不同的类型
1 | int main() |
const_cast
能够删除变量的const属性
1 | int main() |
但是上边的代码会出现一个问题,就是运行结果显示,a还是2,不过当我们打开监视窗口可以看到a其实已经被改成3了,这是什么原因呢?
a被const修饰,编译器以为不会被修改,所以加载到寄存器,虽然内存中已经被改了但是寄存器里面的还是2,cout的时候直接去寄存器读,所以打印出来是2
我们可以在定义a变量的时候加上 volatile关键字,这样编译器处理的时候就会去内存中读取数据,这样,运行结果就变成3 3了。
注:
- 兼容c隐式类型转换和强制类型转换
- 期望不要再用了,最好用规范的cpp显示强制类型转换
- static_cast(隐式类型转换)、reinterpret_cast、const_cast(强制类型转换)
dynamic_cast
用于将一个父类对象的指针或者引用转换为子类的指针或者引用(动态转换)
向上转型:子类对象指针/引用->父类指针/引用 (不需要转换,赋值兼容规则)
向下转型:父类对象指针/引用->子类指针/引用 (用dynamic_cast转型是安全的)
- dynamic_cast只能用于父类含有虚函数的类
- dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回0
1 | class A |
细节部分:
1 | class A1 |
可以看到,强转成子类指针,和dynamic_cast都可以将指针位置偏移到头上
总结:
- 如果有个子类的对象,将地址传给一个函数,函数形参是父类的指针,那么函数内部可以将这个指针重新安全的转成子类的指针。
- 普通的父类指针强转成子类可能有风险,如果父类的指针本来指向的对象就是父类的对象,那么将这个指针转换成子类,会有越界的风险。
RTTI
Run-time Type identification :运行时类型识别
c++通过以下方式支持RTTI
- typeid运算符 (获取对象类型的字符串)
- dynamic_cast运算符 (识别父类的指针是指向父类对象还是子类对象)
- decltype (推导一个对象类型,这个类型可以用来定义另一个对象)
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 芝士就是菜!
评论