一、static_cast:
作用:static_cast < type-id > ( expression ),该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性(编译时类型检查),它主要有如下几种用法:
(1)用于基本数据类型之间的转换,如把int转换为char,把int转换成enum,但这种转换的安全性需要开发者自己保证(这可以理解为保证数据的精度,即程序员能不能保证自己想要的程序安全),如在把int转换为char时,如果char没有足够的比特位来存放int的值(int>127或int<-127时),那么static_cast所做的只是简单的截断,及简单地把int的低8位复制到char的8位中,并直接抛弃高位。
比如下面的例子:int转换为short时,直接把低十六位寄存器ax中的位拷贝到c。
(2)把空指针转换成目标类型的空指针
(3)把任何类型的表达式类型转换成void类型
(4)用于类层次结构中父类和子类之间指针和引用的转换。
对于以上第(4)点,存在两种形式的转换,即上行转换(子类到父类)和下行转换(父类到子类)。对于static_cast,上行转换时安全的,而下行转换时不安全的,为什么呢?因为static_cast的转换时粗暴的,它仅根据类型转换语句中提供的信息(尖括号中的类型)来进行转换,这种转换方式对于上行转换,由于子类总是包含父类的所有数据成员和函数成员,因此从子类转换到父类的指针对象可以没有任何顾虑的访问其(指父类)的成员。而对于下行转换为什么不安全,是因为static_cast只是在编译时进行类型坚持,没有运行时的类型检查。
二、const_cast:
作用:用来强制移除变量的CV属性(这里我们只讨论const属性)。
int i = 1; //改为const int i;
cout << "i turns out to be: " << i << endl;
const int* pc = &i;
int* modifier = const_cast<int*>(pc);
*modifier = 2;
cout << "i now is: " << i << endl;
cout << "*modifier is : " << *modifier << endl;
结果:
如果上例第一句是const int i = 1;
那么再按照这种方式去修改i的值将会产生未定义行为!
其实,const_cast最主要是应用在函数重载中。《Effective C++》中有个很好的例子:
class TextBlock
{
public:
//...
const char& operator[](size_t position) const//常成员函数
{
//...
return text[position];
}
char& operator[](size_t position)
{
//...
return //这里现给调用者加上const属性,
const_cast<char&>( //成为一个const TextBlock对象
static_cast<const TextBlock>(*this) //再调用const operator[]
[position]); //最后移除返回值的const属性,实现安全的代码复用
}
//...
private:
string text;
//...
};
三、reinterpret_cast:
作用:用来处理无关类型之间的转换;它会产生一个新的值,这个值会有与原始参数(expressoin)有完全相同的比特位(比特位的重新解释)。
滥用 reinterpret_cast 运算符可能很容易带来风险。 除非所需转换本身是低级别的,否则应使用其他强制转换运算符之一。
reinterpret_cast 运算符可用于 char* 到 int* 或 One_class* 到 Unrelated_class* 之类的转换,这本身并不安全。
reinterpret_cast 的结果不能安全地用于除强制转换回其原始类型以外的任何用途。 在最好的情况下,其他用途也是不可移植的。
reinterpret_cast 运算符不能丢掉 const、volatile 或 __unaligned 特性。
reinterpret_cast 运算符将 null 指针值转换为目标类型的 null 指针值。
reinterpret_cast 的一个实际用途是在哈希函数中,即,通过让两个不同的值几乎不以相同的索引结尾的方式将值映射到索引。
#include <iostream>
using namespace std;
// Returns a hash code based on an address
unsigned short Hash( void *p ) {
unsigned int val = reinterpret_cast<unsigned int>( p );
return ( unsigned short )( val ^ (val >> 16));
}
using namespace std;
int main() {
int a[20];
for ( int i = 0; i < 20; i++ )
cout << Hash( a + i ) << endl;
}
四、dynamic_cast: