C++中,某些数据类型之间有关联,可以互相转换。比如类型A、B之前有关联,当程序需要类型A的对象时,可以用类型B的对象来代替。分显式转换(explicit)和隐式转换(implicit)。有些转换是程序自动完成的,无需程序员介入,这些是隐式转换,如下:

  1. int i = 3.1415926 + 1; // 4,
  2. // 1、1隐式转换成double型
  3. // 2、计算和,返回double型
  4. // 3、将计算结果转换成int型。

隐式转换

编译器自动完成的转换。可能发生情形:

  • 比int小的整型值首先提升为较大的整型。
  • 在条件中,非bool转换成bool
  • 初始化过程中,初始值转换成变量的类型 ; 在赋值语句中,右侧运算对象转换成左侧运算对象的类型。
  • 如果算术运算或关系运算的运算对象有多种类型,需要转换成同一种类型 。
  • 函数调用时,实参初始化形参也会发生类型转换 。

    算术转换

    总的原则就是小的往大的转,范围小的往范围大的转。
  1. bool flag; char cval;
  2. short sval; unsigned short usval;
  3. int ival; unsigned int uival;
  4. long lval; unsigned long ulval;
  5. float fval; double dval;
  6. 3 .14159L +'a'; // 'a , 提升成 int ,然后该 int 值转换成 long double
  7. dval + ival; // ival 转换成 double
  8. dval + fval; // fval 转换成 double
  9. ival = dval; // dval 转换成(切除小数部分后) int
  10. flag = dval; // 如果 dval 是 0. 则 flag 是 false , 否则 flag 是 true
  11. cval + fval; // cval 提升成 int,然后该 int 值转换成 float
  12. sval + cval; // sval 和 cval 都提升成 int
  13. cval + lval; // cval 转换成 long
  14. ival + ulval; // ival 转换成 unsigned long
  15. usval + ival; // 根据 unsigned short 和 int 所 占 空 间的大小进行提升
  16. uival + lval; // 根据 unsigned int 和 long 所 占空间的大小 进行转换

其他隐式转换

  1. int ia[10]; // 含有10个整数的数组
  2. int* ip = ia ; // ia转换成指向数组首元素的指针
  3. char *cp = get_string() ;
  4. if (cp) /*... */ // 如果指针cp不是0, 条件为真
  5. while (*cp) /*... */ // 如果*cp不是空字符,条件为真
  6. int i ;
  7. const int &j = i; // 非常量转换成const int的引用
  8. const int *p = &i; // 非常量的地址转换成const的地址
  9. int &r = j , *q = p; // 错误:不允许const转换成非常量
  10. string s, t = "a value "; // 字符串字面值转换成string类型
  11. while (cin >> s ) // while的条件部分把cin转换成布尔值

显式转换(强制类型转换)

谨慎使用,非常容易出错。

  1. // 强制类型转换公式:
  2. // type: 要转换成的类型
  3. // cast_name: 下面四种值的一种。
  4. // static_cast,没有底层const的都可以转。
  5. // dynamic_cast,动态类型转换,基类指针或引用转换成派生类。
  6. // const_cast,改变底层const
  7. // reinterpret_cast,对内存内容进行重新解释,机器相关,谨慎使用。类似C的(char*)ip效果。
  8. cast_name<type> (expression);
  9. /****************static_cast例子******************/
  10. // 对“较大”的算术类型转成“较小”的算术类型有用
  11. // 对编译器无法自动执行的类型转换也非常有用
  12. double slope = static_cast<double>(j) / i;
  13. void* p = &d; // 正确:任何非常量对象的地址都能存入void*
  14. double *dp = static_cast<double*>(p); // 正确:将void*转换回初始的指针类型
  15. /****************const_cast例子******************/
  16. const char *pc;
  17. char *p = const_cast<char*>(pc); // 正确:但是通过 p 写值是未定义的行为
  18. const char *cp ;
  19. char *q = static_cast<char*>(cp); // 错误 :static_cast不能转换掉const性质
  20. static_cast<string>(cp); // 正确:字符串字面值转换成string类型
  21. const_cast<string>(cp); // 错误:const_cast只改变常量属性
  22. /****************reinterpret_cast例子******************/
  23. int *ip;
  24. char *pc = reinterpret_cast<char*>(ip); // 正确,但务必清楚操作的意义,极容易出错。
  25. string str(pc); // 报错,
  26. /****************C风格的类型转换******************/
  27. // 在C++中应该摒弃这种C风格的转换方式,因为上面的cast完全可以代替。
  28. char *pc = (char*)ip; // 效果和reinterpret_cast一样