static_cast
在C++中强制类型转换存在四种方式,分别是static_cast、const_cast、rinterpret_cast和dynamic_cast。前三种对应这在c语言中旧式的强制类型转换,这篇文章讲解一下static_cast
static_cast关键字主要用于以下集中情况:
1)基本类型之间的转换,但不能用于基本类型指针之间的类型转换(void指针和基本类型指针之间可以)
例如:
double d=0; int i=static_cast<int>(d);
2)用于有继承关系的子类与父类之间的指针或引用的转换
3)空类型指针转换为任意基本类型的指针
第三条是这里面很容易出错,因为有可能出现未知的转换结果,要保证转换的正确性就必须保证转换后所得的类型就是指针原先的类型。
先看一个转换正确的例子
代码如下:
int i=0; void *vp=&i; int *p=static_cast<int*>(vp); *p=3; cout<<i<<endl;
输出结果是 3
我们分析一下: i的初始类型为int 然后我们将i的地址转换为void*,然后void指针vp转换为int指针,此时int型指针 p和vp指向的i的原始类型int一致,所以转换结果正确。
接下来再看几个错误的例子
例1:
代码如下:
int i=3; void *vp=&i; char *p=static_cast<char*>(vp); *p=4 cout<<i<<endl;
输出结果是 4
我们分析一下:初看来我们的结果是正确的,但是这里实际是有错误的,或者说是不安全的转换。考虑如下代码:
int i=256; void *vp=&i; char *p=static_cast<char*>(vp); *p=4; cout<<i<<endl;
输出结果是 260
这是为什么呢,让我们来分析一下。上面的两个例子都是错误的,原因就在于,最后转换的类型与数据的初始类型是不一样的,但是为什么输出结果一个正确,一个却是错误的呢。原因就在于不同的数据类型占用的字节数是不一样的,在我的机器里char是一个字节也就是8位,int是4字节,也就是32位,在第一个例子里3的二进制是0…0 0000 0011,那么在转换为char指针时实际指向低8位数据空间,也就是00000011所在位置,然后经过p=4以后,变为00000100,因此数据i的二进制就变成了0…0 0000 0100 ,也就是4,虽然结果没错,但是是不安全的,而第二个例子就体现了不安全。
同样对第二个例子进行分析。256的二进制是0000 0000 0000 0000 0000 0001 0000 0000,转换后char指针仍然指向低8位所在的数据空间,也就是0000 0000所在位置,然后经过p=4以后,变为00000100,因此数据i的二进制就变成了0000 0000 0000 0000 0000 0001 0000 0100,转换成十进制就是260。
接下来再看一个例子
int i=4294967294; void *vp=&i; double *p=static_cast<double*>(vp); *p=4; cout<<i<<endl;
输出结果是0
这里出现错误同样是和上面的两个例子一样,之所以结果是0,我个人的理解是由于浮点型表示形式不同所导致的。