C++类型转换分为:隐式类型转换和显式类型转换
第1部分. 隐式类型转换
又称为“标准转换”,包括以下几种情况:
算术转换(Arithmetic conversion) : 在混合类型的算术表达式中, 最宽的数据类型成为目标转换类型。
int ival = 3; double dval = 3.14159; ival + dval; // ival被提升为double类型
一种类型表达式赋值给另一种类型的对象:目标类型是被赋值对象的类型
int *pi = 0; // 0被转化为int *类型 ival = dval; // double->int
例外:void指针赋值给其他指定类型指针时,不存在标准转换,编译出错
将一个表达式作为实参传递给函数调用,此时形参和实参类型不一致:目标转换类型为形参的类型
extern double sqrt(double); cout << "The square root of 2 is " << sqrt(2) << endl; // 2被提升为double类型:2.0
从一个函数返回一个表达式,表达式类型与返回类型不一致:目标转换类型为函数的返回类型
double difference(int ival1, int ival2) { return ival1 - ival2; // 返回值被提升为double类型 }
第2部分. 显式类型转换
被称为“强制类型转换”(cast)
C 风格: (type-id)
C++风格: static_cast、dynamic_cast、reinterpret_cast、和const_cast..
最好的解决方法就是不要使用C风格的强制类型转换,而是使用标准C++的类型转换符:static_cast, dynamic_cast。标准C++中有四个类型转换符:static_cast、dynamic_cast、reinterpret_cast、和const_cast。下面对它们一一进行介绍。
static_cast
- 用法:static_cast < type-id > ( expression )
说明:该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性。
来源:为什么需要static_cast强制转换?
情况1:void指针->其他类型指针
情况2:改变通常的标准转换
情况3:避免出现可能多种转换的歧义它主要有如下几种用法:
用于类层次结构中基类和子类之间指针或引用的转换。进行上行转换(把子类的指针或引用转换成基类表示)是安全的;进行下行转换(把基类指针或引用转换成子类指针或引用)时,由于没有动态类型检查,所以是不安全的。
- 用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。
- 把void指针转换成目标类型的指针(不安全!!)
把任何类型的表达式转换成void类型。
注意:static_cast不能转换掉expression的const、volitale、或者__unaligned属性。
最常用的类型转换符,在正常状况下的类型转换,如把int转换为float,如:
int i;
float f;
f=(float)i;
或者
f=static_cast<float>(i);
const_cast
用于取出const属性,把const类型的指针变为非const类型的指针,如:
const int *fun(int x,int y){}
int *ptr=const_cast<int *>(fun(2.3))
dynamic_cast
- 用法:dynamic_cast < type-id > ( expression )
说明:该运算符把expression转换成type-id类型的对象。Type-id必须是类的指针、类的引用或者void*;如果type-id是类指针类型,那么expression也必须是一个指针,如果type-id是一个引用,那么expression也必须是一个引用。
源:为什么需要dynamic_cast强制转换?
简单的说,当无法使用virtual函数的时候
dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。
- 在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。
该操作符用于运行时检查该转换是否类型安全,但只在多态类型时合法,即该类至少具有一个虚拟方法。dynamic_cast与static_cast具有相同的基本语法,dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。如:
class C
{
//…C没有虚拟函数
};
class T{
//…
}
int main()
{
dynamic_cast
interpret_cast
interpret是解释的意思,reinterpret即为重新解释,此标识符的意思即为数据的二进制形式重新解释,但是不改变其值。
如:
int i;
char *ptr="hello freind!";
i=reinterpret_cast<int>(ptr);
这个转换方式很少使用。