C++中的类型转换
显示转换
命名的强制类型转换
- static_cast
- dynamic_cast
- const_cast
- reinterpret_cast
cast-name<type>(expression)
//其中type是转换的目标类型,expression是要转换的值
//castname是上表所列的4个转换类型名中的一种
static_cast
任何具有明确定义的类型转换,只要不包含底层const,都可以使用static_cast。
int i,j;
double slope = i/j;
double slope = static_cast<double>(j)/i;//强制转换以便执行浮点除法。
当一个较大的算术类型转换成一个较小的算术类型,如果没有使用static_cast 就会显示警告,使用static_cast警告就消失了,因为编译器已经默认接受可能出现的精度损失。
static_cast对于编译器无法自动执行的类型转换也非常有用。
void *p = &d;
double *dp = static_cast<double* >(p);
const_cast
const_cast 只能改变运算对象的底层const
const char *pc;
char *p = const_cast<char*>(pc);
如果对象本身不是一个常量,使用强制类型转换获得写的权限是合法的行为,然而如果对象是一个常量,再使用const_cast执行写操作就会产生未定义的后果。
reinterpret_cast
reinterpret_cast 通常为运算对象的位模式提供较低层次上的重新解释。
int *ip;
char *pc = reinterpret_cast<char *>(ip);
我们必须牢记pc所指的真实对象是一个int而非字符,如果把pc当成普通的的字符串指针使用就可能在运行时发生错误。
string str(pc); //会发生错误。
当我们用一个int的地址初始化pc时,由于显式的声称这种转化合法,所以编译器不会发出任何警告或错误信息。
const的分层问题
顶层const
用名词顶层const(top-level const)表示指针本身是个常量,而用名词底层const(low-level const)表示指针所指对象是一个常量。
更一般的,顶层const可以表示任意的对象是常量。
底层const则与指针和引用等复合类型的基本类型部分有关。
指针类型既可以是顶层const又可以是底层const
int i = 0;
int* const p1 = &i; //不能改变p1的值是一个顶层const
const int ci = 42; //不能改变ci的值是一个顶层const
const int *p2 = &ci; //可以改变p2的值是一个底层const
const int *const p3 = p2; //靠右边的是顶层const,靠左边的是底层const
const int &r = ci; //r 是底层const
底层const的限制不能忽视,当执行对象的拷贝操作时,拷入拷出的对象必须有相同的底层const资格。或者两个对象的数据类型必须能够转换,非常量可以转换成常量,反之则不行。
int *p = p3; //p没有底层const的资格,不能进行。
p2 = p3; //p2,p3均有底层const的资格
p2 = &i; //正确,int* 能转换成const int*
int &r = ci; //普通的int & 不能绑定在 int 常量上。
const int &r2 = i; //const int & 可以绑定到一个普通int 上。
网友评论