有时咱们但愿显式地将对象强制类型转换成另一种类型。例如,若是想在下面的代码中执行浮点数除法:express
int i, j;spa
double slope = i / j;指针
就要使用某种方法将i和/或j显式地转换成double,这种方法称做强制类型转换。code
命名的强制类型转换对象
一个命名的强制类型转换具备以下形式:blog
cast_name<type>(expression);ip
其中,type是转换的目标类型而expression是要转换的值。若是type是引用类型,则结果是左值,cast-name是static_cast, dynamic_cast, const_cast和reinterpret_cast中的一种。dynamic_cast支持运行时类型识别。cast-name指定了执行的是哪一种转换。字符串
static_cast编译器
任何具备明肯定义的类型转换,只要不包含底层const,均可以使用static_const。string
例如,经过将一个运算对象强制转换成double类型就能使表达式执行浮点数除法:
double slope = static_cast<double>(j) / i;
当须要把一个较大的算术类型赋值给较小的类型时,static_cast很是有用。此时,强制类型转换告诉程序的读者和编译器:咱们知道而且不在意潜在的精度损失。通常来讲,若是编译器发现一个的算术类型试图赋值给较小的类型,就会给出警告信息;可是当咱们执行了显式的类型转换后,警告信息就会被关闭了。
static_cast对于编译器没法自动执行的类型转换也很是有用。例如,咱们可使用static_cast找回存在于void*指针中的值:
void *p = &d; //正确:任何很是量对象的地址都能存入void*
//正确:将void*转换回初始的指针类型
double *dp = static_cast<double*>(p);
当咱们把指针存放在void*中,而且使用static_cast将其强制转换回原来的类型时,应该确保指针的值保持不变。也就是说,强制转换的结果将与原始的地址值相等,所以咱们必须确保转换后所得的类型就是指针所指的类型。类型一旦不符,将产生未定义的后果。
const_cast
const_cast只能改变运算对象的底层const
const char *pc;
char *p = const_cast<char*> (pc); //正确:可是经过p写值是未定义的行为
对于将常量对象转化为很是量对象的行为,咱们通常称之为”去掉const性质(cast away the const)“。一旦咱们去掉了某个对象的const性质,编译器就再也不阻止咱们对该对象进行写操做了。若是对象自己不是一个常量,使用强制类型转换得到写权限是合法的行为。然而若是对象是一个常量,再使用const_cast执行写操做就会产生未定义的后果。
只有 const_cast能改变表达式的常量属性,使用其余形式的命名强制类型转换改变表达式的常量属性都将引起编译器错误。一样地,也不能用const_cast改变表达式的类型:
const char *cp; //错误:static_cast不能转换掉const性质 char* q = static_cast<char*> (cp); static_cast<string> (cp); //正确,字符串字面值转换成string类型 const_cast<string>(cp); //错误,const_cast只改变常量属性
总结来讲:const_cast只能改变底层const,即它只能改变对象或引用的const属性,不能改变对象的const属性。const_cast便可以添加const性质,也能够删除const性质。
reinterpret_cast
reinterpret_cast一般为运算对象的位模式提供较低层次上的从新解释。举个例子,假设有以下的转换:
int *ip;
char *pc = reinterpret_cast<char*>(ip);
咱们必须牢记pc所指的真实对象是int而非字符,若是把pc当成一个普通的字符指针使用就可能在运行时发生错误。例如:
string str(po);
可能致使异常的运行时行为。
使用reinterpret_cast是很是危险的,用pc初始化的例子很好地证实了这一点。其中的关键问题是类型改变了,但编译器没有给出任何警告或者错误的提示信息。当咱们用一个int的地址初始化pc时,因为显式地声称这种转换合法,因此编译器不会发出任何警告或错误信息。接下来再使用pc时就会认定它的值是char*类型,编译器无法知道它实际存放的是指向int的指针。
dynamic_cast
只用于对象的指针和引用. 当用于多态类型时,它容许任意的隐式类型转换以及相 反过程. 不过,与static_cast不一样,在后一种状况里(注:即隐式转换的相反过程),dynamic_cast 会检查操做是否有效. 也就是说, 它会检查转换是否会返回一个被请求的有效的完整对象。检测在运行时进行. 若是被转换的指针不是一个被请求的有效完整的对象指针,返回值为NULL. 对于引用 类型,会抛出bad_cast异常 .