查看原文
其他

4 种 C++ 强制类型转换,你都清楚吗?

张宗豪 CPP开发者 2021-06-06

(给CPP开发者加星标,提升C/C++技能)


我们先来回忆以下,C 语言的强制类型转换形式:

(type) expr;

这种旧式强制类型转换从表现形式上来说不够清晰明了,容易看漏,一旦转换过程出现问题,追踪起来也就更加困难。


为了解决以上问题,C++不仅兼容了C的强制转换,来引入了新的转换方法。


强制类型转换的形式:

cast-name<type>(exper);

其中,type是转换的目标类型,exper是要转换的值,cast-name 有以下四种:

  1. static_cast

  2. dynamic_cast

  3. const_cast

  4. reinterpret_cast


接下来,我们逐个进行分析。


1、static_cast


这里先介绍下顶层const和底层const的概念:


(1)顶层const,表示指针本身是常量,例如:

int *const p1 = &i;p1 = &j;       //编译报错,不能修改p1指向++(*p1); //可以,可以修改p1所指向的值的内容

(2)底层const,表示指针所指的对象是一个常量,例如:

const int *p2 = &i;p2 = &j;       //可以,可以修改p2的指向++(*p2); //编译报错,不能修改p2所指向的值的内容

那么再来说说static_cast:任何具有明确定义的类型转换,除了不包含底层const,都可以使用 static_cast。例如:

double d = 0.1;void* p = &d; double *dp = static_cast<double*>(p);

static_cast本质上是传统c语言强制转换的替代品。


通常,该操作符用于非多态类型的转换,任何标准转换都可以使用它。


2、dynamic_cast


用于将基类指针或引用安全的转换成派生类的指针或引用(运行时类型识别)。


dynamic_cast运算符的使用形式如下:

dynamic_cast<type*>(e)dynamic_cast<type&>(e)dynamic_cast<type&&>(e)

其中,type必须是一个类类型,并且通常情况下该类型应该含有虚函数,在第一种形式中,e必须是有效指针;在第二种形式中,e必须是一个左值,在第三种形式中,e不能是左值。


如果转换目标是指针并且转换失败,则结果是0,如果转换目标是引用并且转换失败的,则会抛出异常。


因此,dynamic_cast操作符一次执行两个操作。首先验证被请求的转换是否有效,只有转换有效,操作符才实际进行转换。


3、const_cast


只能用于改变运算对象的底层const(去掉const属性)

例:

const char *p1;char* p2 = const_cast<char*>(p1);

注意,我们去掉了const属性,编译器不会再阻止我们对该对象进行写操作,但要注意,通过p2写值是未定义行为。


4、reinterpret_cast


该操作符用于将一种类型转换为另一种不同的类型,


比如可以把一个指针类型转换为一个整数,再把整数转换为指针类型,并且还是原来那个指针。


“通常为运算对象的位模式提供较低层次上的重新解释“,即是将变量以二进制形式被重新解释为新的类型,这个操作本质是依赖于机器的,也就是说,还需要考虑移植性。要想安全的使用reinterpret_cast,必须对涉及的类型和编译器实现转换的过程都非常了解。


reinterpret_casts 的最普通的用途,就是在函数指针类型之间进行转换。


简单总结


  1. 基本类型(非多态)的转换用static_cast。

  2. 多态类之间的类型转换用dynamic_cast。

  3. 去掉const属性用const_cast。

  4. 不同类型的指针类型转换用reinterpreter_cast。(慎用)



欢迎在评论中和我探讨。觉得文章不错,请点赞和在看支持我继续分享好文。谢谢!



- EOF -


推荐阅读  点击标题可跳转

1、C++ 初始化的坑,你也遇到过吗?

2、NVIDIA 开源 C++ 标准库 Libcu++

3、TIOBE 9月编程语言排行榜发布,C++增速最快,C++20 的功劳?


看完本文有帮助?请分享给更多人

关注「CPP开发者」加星标,提升C/C++技能

好文章,我在看❤️

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存