C++中,某些数据类型之间有关联,可以互相转换。比如类型A、B之前有关联,当程序需要类型A的对象时,可以用类型B的对象来代替。分显式转换(explicit)和隐式转换(implicit)。有些转换是程序自动完成的,无需程序员介入,这些是隐式转换,如下:
int i = 3.1415926 + 1; // 4,// 1、1隐式转换成double型// 2、计算和,返回double型// 3、将计算结果转换成int型。
隐式转换
编译器自动完成的转换。可能发生情形:
- 比int小的整型值首先提升为较大的整型。
- 在条件中,非bool转换成bool
- 初始化过程中,初始值转换成变量的类型 ; 在赋值语句中,右侧运算对象转换成左侧运算对象的类型。
- 如果算术运算或关系运算的运算对象有多种类型,需要转换成同一种类型 。
- 函数调用时,实参初始化形参也会发生类型转换 。
算术转换
总的原则就是小的往大的转,范围小的往范围大的转。
bool flag; char cval;short sval; unsigned short usval;int ival; unsigned int uival;long lval; unsigned long ulval;float fval; double dval;3 .14159L +'a'; // 'a , 提升成 int ,然后该 int 值转换成 long doubledval + ival; // ival 转换成 doubledval + fval; // fval 转换成 doubleival = dval; // dval 转换成(切除小数部分后) intflag = dval; // 如果 dval 是 0. 则 flag 是 false , 否则 flag 是 truecval + fval; // cval 提升成 int,然后该 int 值转换成 floatsval + cval; // sval 和 cval 都提升成 intcval + lval; // cval 转换成 longival + ulval; // ival 转换成 unsigned longusval + ival; // 根据 unsigned short 和 int 所 占 空 间的大小进行提升uival + lval; // 根据 unsigned int 和 long 所 占空间的大小 进行转换
其他隐式转换
int ia[10]; // 含有10个整数的数组int* ip = ia ; // ia转换成指向数组首元素的指针char *cp = get_string() ;if (cp) /*... */ // 如果指针cp不是0, 条件为真while (*cp) /*... */ // 如果*cp不是空字符,条件为真int i ;const int &j = i; // 非常量转换成const int的引用const int *p = &i; // 非常量的地址转换成const的地址int &r = j , *q = p; // 错误:不允许const转换成非常量string s, t = "a value "; // 字符串字面值转换成string类型while (cin >> s ) // while的条件部分把cin转换成布尔值
显式转换(强制类型转换)
谨慎使用,非常容易出错。
// 强制类型转换公式:// type: 要转换成的类型// cast_name: 下面四种值的一种。// static_cast,没有底层const的都可以转。// dynamic_cast,动态类型转换,基类指针或引用转换成派生类。// const_cast,改变底层const// reinterpret_cast,对内存内容进行重新解释,机器相关,谨慎使用。类似C的(char*)ip效果。cast_name<type> (expression);/****************static_cast例子******************/// 对“较大”的算术类型转成“较小”的算术类型有用// 对编译器无法自动执行的类型转换也非常有用double slope = static_cast<double>(j) / i;void* p = &d; // 正确:任何非常量对象的地址都能存入void*double *dp = static_cast<double*>(p); // 正确:将void*转换回初始的指针类型/****************const_cast例子******************/const char *pc;char *p = const_cast<char*>(pc); // 正确:但是通过 p 写值是未定义的行为const char *cp ;char *q = static_cast<char*>(cp); // 错误 :static_cast不能转换掉const性质static_cast<string>(cp); // 正确:字符串字面值转换成string类型const_cast<string>(cp); // 错误:const_cast只改变常量属性/****************reinterpret_cast例子******************/int *ip;char *pc = reinterpret_cast<char*>(ip); // 正确,但务必清楚操作的意义,极容易出错。string str(pc); // 报错,/****************C风格的类型转换******************/// 在C++中应该摒弃这种C风格的转换方式,因为上面的cast完全可以代替。char *pc = (char*)ip; // 效果和reinterpret_cast一样
