(一) 隐性类型转换
定义
所谓隐性类型转换,指的是不需要用户干预的情况下,编译自动进行的类型转换行为。
好处
C++是强类型语言,对类型检查严格。因此隐性类型转换能给程序员带来些便利。
转换原则
把一个数值从取值范围较小的类型转换为取值范围较大的类型,避免精度损失。例如从int到float,从float到double。
发生条件
(1) 混合类型的算术表达式
(2) 不同类型的赋值操作
(3) 函数的参数传值
(4) 函数的返回值
在这些情况下,当然也可以采用显式类型转换。
风险
隐性类型转换的风险一般只发生于自定义的类构造函数中。
按照默认规定,只有一个参数的构造函数也定义了一个隐式转换,将该构造函数对应的数据类型的数据转换为该类对象。举例如下:
#include <iostream>
#include <string>
using namespace std;
class Pencil{
public:
Pencil(int len=10):m_length(len){}
~Pencil(){}
bool isSame(const Pencil& other)
{
return this->m_length == other.m_length;
}
public:
int m_length;
};
int main(char* args[])
{
Pencil redPencil = 15; // implicit conversionConstructor to convert from 'int' to 'Pencil'
Pencil whitePencil(5);
if(whitePencil.isSame(5)) // implicit conversion from "int" to "Pencil"
cout << "whitePencil is same as 5!!!" << endl;
return 0;
}
使用
关键字explicit禁止隐式转换,在构造函数前添加explicit即可。
(二) 显性类型转换
显性类型转换又称强制类型转换,C++中有4个类型转换相关的运算符:static_cast,dynamic_cast,reinterpret_cast和const_cast。他们的使用方式基本一样,但应用场合大有不同。
另外,老式的强制类型转换依然有效,其语法包含了这4种转换。
(转换后的类型)表达式
由于老式的强制类型转换语义并不是很清晰,可能得不到希望的结果,代码更容易出错。因此在代码中最好使用新型的强制类型转换语法。
1. static_cast
静态类型转换,编译期间进行类型检查和强制转换。
用法:static_cast<转换后的类型>(表达式)
(1) 用于类层次中子类和基类之间的指针或引用转换
上行转换,即将子类的指针或引用转换为基类引用,是安全的;
下行转换,即将基类的指针或引用转换为子类引用,由于没有动态类型检查,是不安全的;
(2) 基本数据类型间的类型转换,如从float到int,安全性由程序员把握;
(3) 空指针转换为目标类型的空指针;
(4) 任何类型的表达式转换为void类型。
注意:static_cast不能转换掉表达式的const,volitle或者_unaligned属性。
2. dynamic_cast
动态强制转换,专门用于转换类层次结构中类类型的指针和引用。
注意要强制转换的类型必须是同一类层次结构中的类的指针或者引用。或者说多态类类型(至少包含一个虚函数的类类型)。
用法:dynamic_cast<转换后的类型>(表达式)
转换后的类型必须是类的指针、类的引用或者void*,且与(表达式)一一对应。
在类层次进行上行转换时,dynamic_cast与static_cast的效果一样;但进行类层次的下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。
注意:dynamic_cast不能转换掉表达式的const,volitle或者_unaligned属性。
3. reinterpret_cast
强制指针转换,reinpterpret_cast<>()运算符允许强制转换任何指针类型,其限制是如果要强制转换的指针类型声明为const,就不能把它强制转换为非const类型。还可以把整数型强制转换为指针类型,或者把指针类型强制转换为整型值。这不会改变所涉及的值,只会改变解释值的方式。一般用法如下:
reinterpret_cast<指针类型>(表达式)
特别强调,reinterpret<>()运算符是很危险的,因为它提供了把一种类型的值随意解释为另一种类型的方式。
4. const_cast
常量的强制转换,主要用于将常量对象作为参数传递给另一个函数,该函数由他人编写且需要非常量的参数的场合。用法如下:
const_cast<转换后的类型>(表达式)
表达式的类型必须是const类型,且与<转换后的类型>一致。
参考资料:C++入门经典,C++Prime