您的位置:首页 > 其它

static_cast,reinterpret_cast及C的强制类型转换

2015-11-10 11:44 218 查看
static_cast和C的强制类型转换,在结果上没有任何区别,编译器都会自动完成转换的截断,补齐或者指针偏移。唯一的区别是编译警告和报错:

class A
{
    int a;
};

class B
{
    int b;
};

class C : public A
{
    int c;
};

int main()
{
    B b;
    C c;
    
    A* p1 = (A*) &b; // 这句是c风格的强制类型转换,编译不会报错,留下了隐患
    A* p2 = static_cast<A*>(&b); // static_cast在编译时进行了类型检查,直接报错

}

static_cast,reinterpret_cast区别:

static_cast 运算符完成*相关类型*之间的转换. 而 reinterpret_cast 处理*互不相关的类型*之间的转换.

所谓"相关类型"指的是从逻辑上来说,多多少少还有那么一点联系的类型,比如从 double 到 int,我们知道它们之间还是有联系的,只是精度差异而已,使用 static_cast 就是告诉编译器:我知道会引起精度损失,但是我不在乎. 又如从 void* 到 具体类型指针像 char*,从语义上我们知道 void* 可以是任意类型的指针,当然也有可能是 char* 型的指针,这就是所谓的"多多少少还有那么一点联系"的意思.
又如从派生类层次中的上行转换(即从派生类指针到基类指针,因为是安全的,所以可以用隐式类型转换)或者下行转换(不安全,应该用 dynamic_cast 代替).
对于static_cast操作符,如果需要截断,补齐或者指针偏移编译器都会自动完成.注意这一点,是和 reinterpret_cast 的一个根本区别.

"互不相关的类型"指的是两种完全不同的类型,如从整型到指针类型,或者从一个指针到另一个毫不相干的指针.
示例:
int ival = 1;
double *dptr = reinterpret_cast<double*>(ival);

或者
int *iptr = NULL;
double *dptr = reinterpret_cast<double*>(iptr);

reinterpret_cast 操作执行的是比特位拷贝,就好像用 memcpy() 一样.

int *iptr = reinterpret_cast<int*>(1);
double *dptr = reinterpret_cast<double*>(2);
memcpy(&dptr, &iptr, sizeof(double*)); // 等效于 dptr = reinterpret_cast<double*>(iptr); 结果 dpt
4000
r 的值为1;

上面这个示例也说明了 reinterpret_cast 的意思:编译器不会做任何检查,截断,补齐的操作,只是把比特位拷贝过去.
所以 reinterpret_cast 常常被用作不同类型指针间的相互转换,因为所有类型的指针的长度都是一致的(32位系统上都是4字节),按比特位拷贝后不会损失数据.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: