cpp中的类型转换

参考资料

类型安全

文章首先说什么是类型安全,其实定义并不简单,变量在定义之后,没有经过任何显示或者隐式的转换前,都是安全的。安全意味着什么?意味着变量,函数参数,返回值存储着一种可接受的数据,可接受意味着,和这些数据相关的操作是有意义的,合理的,不会有数据的丢失,不会被错误的解析,不会被污染,但是同时数据转换又是需要的。但是很多时候这种转换都是不安全的,只要是会引起数据丢失或者数据被重新解释的情况,都可以说是不安全的。比如int转为float,unsigned 转为 signed。

编译器的反映

对于不安全的转换,编译器有两个反映,一个种是error,一种是warning。而且就算编译器没有告警,错误还是可能被隐式转换或者显示转换引入。

隐式转换

当表达式中存在不相同的数据类型时,编译器就会按照内建的标准转换约定对数据进行转换。如果转换是一个promotion,我也不清楚该怎么翻译,那么编译器不会产生任何告警,而如果转换是narrowing,那编译器就会告警,因为存在数据的丢失。并建议我们将这种告警当作错误来看待。比如double变量复制给float变量。在cpp中,更多涉及的是用户定义的类型,这事编译器会从类型定义中常识找到可以接受的转换,否则,编译器将会报错。当然,这也是有一定的标准的。可以参见连接中的说明。

宽转换

宽转换就是上一段中说的promotion,不会导致数据丢失,所以都是安全的。编译器自然也不会告警。宽转换或者窄转换都都可能隐式得进行。在窄转换中,进过确认没有问题时,建议改为显示转换,这样编译器也就不会报错。

unsigned 和 signed

这两者之间的转换是没有任何告警的,所以在代码中,我们尽量避免直接的转换,至少在转换前需要对值的范围进行判断。

显示转换

除非两个类型完全不相关,否则编译器一般不会报错。就算有时候是不安全的,也只是会告警而已。

转换语法

C语言中的类型转换用的是小括号,而小括号在cpp里也是一中运算符。所以C语言的转换语法,在cpp里就等同于调用operator(),所以很多时候这也是不用一察觉的一种方式。不管是下面两种中的哪种,都是不好的方式:

(int)x
int(x)

因为这两种方式都不用意看出来,而且也不方便搜索。所以建议使用如下几种cpp语法的新的显示转换语法:

  • static_cast 编译时类型校验,一般这也用在基类指针和派生类指针之间转换使用。既然是编译型校验,那就是在编译时就对错误进行检测,如果两种类型无法兼容,那么这个转换就会报错。
  • dynamic_cast:运行时转换,据说这个比static_cast安全,但是也需要有跟多的开销。
  • const_cast:一般用在const转非const,感觉应该用的不多。
  • reinterpret_cast 不相关类型之间的转换,比如 pointer to int

于是下一个问题是,const_cast有什么意义,是不是另外构造了一个值?实现原理是怎样的?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值