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 double
dval + ival; // ival 转换成 double
dval + fval; // fval 转换成 double
ival = dval; // dval 转换成(切除小数部分后) int
flag = dval; // 如果 dval 是 0. 则 flag 是 false , 否则 flag 是 true
cval + fval; // cval 提升成 int,然后该 int 值转换成 float
sval + cval; // sval 和 cval 都提升成 int
cval + lval; // cval 转换成 long
ival + ulval; // ival 转换成 unsigned long
usval + 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一样