导读
提到类型转换,相信有过编程经验的小伙伴们都不陌生了。之前笔者在《NDK编程Java如何保存C或C++对象》一文就中使用了类型强转的方式。
既然C++是继承于C的语言,那么它在类型转换上又做了哪些扩展呢?
C语言式转换
C语言式的类型转换很简单,通过一个括号即可完成强转:。虽然C语言式转换简单,但是它是有不少缺点的,比如它可以在任意类型之间进行转换,比如将const类型的对象转换成非const类型的对象,可以将一个基类的对象指针转化成一个派生类的对象指针等。这些强制转换对于C++来说显然是不太合理的,c++为了克服这些缺点,引进了4新的类型转换操作符,他们分别是:静态类型转换、动态类型转换、常类型转换和重解析类型转换。
C++的类型转换
1、静态类型转换静态类型转换使用的是,它可以被用于强制隐型转换,例如将non-const对象转型为const对象,将int转型为double等,它还可以用于很多这样的转换的反向转换,例如,void* 指针转型为有类型指针,基类指针转型为派生类指针等。
所谓静态类型,就是在编译器就能确定的类型,静态类型转换的使用格式是:
static_cast(标识符)
例如:
2、动态类型转换与静态类型转换相对的是动态类型转换,动态类型是表示在编译期间不能确定的类型,需要到运行时才能确定的类型,它使用标识,它格式是
dynamic_cast(标识符)
动态类型转换的一个重要作用就是将父类对象转换成派生类的对象,如果转换失败则会返回空指针。
例子:
dynamic_cast的转换一定要建立在多态的基础上,也就是说父类一定要有一个虚函数或者纯虚函数才行,否则转换是编译不通过的。
3、常类型转换常类型转换又叫脱常转换,意思就是可以将一个const变量转换成一个非const变量,使用的标识符是。
** const_cast 最常见的用途就是将某个对象的常量性去除掉,并且只能应用于指针或引用。**
我们知道const对象只能调用const的函数,那么如果const对象也想调用非const函数怎么办?这时候就需要使用进行脱常了。
我们来看下以下的两个例子:
以上两个例子当中,为什么一个类通过const_cast转换之后在函数内部修改该类的成员变量后会生效,而int类型经过了const_cast转换后在函数内部修改了值却不生效呢?
这里需要记住一个结论:
使用const_cast去除const限定的属性的目的不是为了修改它的内容,而是是为了函数能够接受这个实际参数。因此使用const_cast去除const限定的属性的类对象是可以改变成员变量的,但是对于内置数据类型,却表现未定义行为.
4、reinterpret_castreinterpret_cast。是特意用于底层的强制转型,这个操作符的转换结果几乎总是与编译平台息息相关。也就是说reinterpret_casts不具跨平台移植性,所以这里就不多做介绍了。
5、隐式转换
隐式转换给我们带来了便利的同时也会给我们带来各种各样的隐患。
让我们通过以下程序简单看看隐式转换带来的隐患:
在上面的程序中因为隐式转换的存在,可能是简单的赋值操作,却变成了类的构造,给人一种欺骗了我的眼睛的感觉....
如果想要去除隐式转换,彻底消除这样的隐患那该怎么办呢?答案也很简单,就是在类的构造函数上增加关键字即可:
如果你需要进行转换但是又不想接受隐式转换带来的隐患,那怎么办呢?在《More Effective C++》一书中作者给了我们建议:
条款 21:利用重载技术(overload)避免隐式类型转换(implicit type conversions)
领取专属 10元无门槛券
私享最新 技术干货