类型显式转换

命名的强制类型转换:

cast-name<type>(expression);

其中 type 是要转换成的目标类型,expression 是要转换的值。如果 type 是引用类型,则结果是左值。cast-name 指定是哪种转换,有 static_cast, dynamic_cast, const_cast 和 reinterpret_cast。dynamic_cast 支持运行时类型识别。

 

static_cast

任何具有明确定义的类型转换,只要不包含底层 const,都可以使用 static_cast。如:

1 int j = 1, i = 2;
2 
3 double cnt = static_cast<double>(j)/i;
4 
5 cout << cnt << endl;//输出0.5

 

1 const char str[10] = "hello";
2 const char *cp = str;
3 // char *q = static_cast<char*>(cp);//错误:static_cast 不能去掉底层 const 
4 static_cast<string>(cp);//将字符面值转换成string类型,注意底层的const并没有去掉,即cp此时的类型是const string
5 // static_cast<const string>(cp);//和上一句效果一致
6 cout << cp << endl;
7 // cp += "world";//错误:const string 类型不能直接改变值

 

static_cast 对于把较大的算术类型赋值给较小的类型(编译器可能会发出警告,使用 static_cast 后能去除警告信息),以及对于编译器无法自动执行的类型转换非常有用。如:

1 double cnt = 1.23;
2 
3 void *p = &cnt;
4 
5 double *q = static_cast<double*>(p);//将p还原成于cnt对应的double*类型
6 
7 cout << *q << endl;//输出1.23

 

在上面的代码中需要注意的是:当我们把指针存放在 void* 中,并且使用 static_cast 将其强制转换为原来的类型时,应该确保指针的值保持不变。即强制转换额结果将与原来的地址值相等。因此我们必须确保转换后所得的类型就是指针所指的类型。类型一旦不符,将产生未定义的后果。如:

 1 int cnt = 1;
 2 
 3 void *p = &cnt;
 4 
 5 cout << p << endl;
 6 
 7 double *q = static_cast<double*>(p);//将原来的int*转换成double*,*q将会是一个随机值
 8 
 9 cout << q << endl;
10 
11 cout << *q << endl;//在本次实验的pc上输出1.15686e-306

 

const_cast:

const_cast 只能改变底层const。如:

1 const char str[10] = "hello";
2 const char *cp = str;
3 const_cast<char*>(cp);//const_cast能去掉底层const
4 cp = "hello world";
5 cout << cp << endl;//输出hello world
6 const int cnt = 1;
7 // const_cast<int>(cnt);//错误,const_cast不能改变顶层const
8 int yy = 1;
9 // const_cast<double>(yy);//错误,const_cast只能去掉底层const而不能做其他类型转换

const_cast 常常用于有函数重载的上下文中。

 

reinterpret_cast:

reinterpret_cast 通常为运算对象的位模式提供较低层次上的重新解释。如:

int *ip;

char *pc = reinterpret_cast<char*>(ip);

我们必须牢记 pc 所指的真实对象是一个 int 而非字符,如果把 pc 当成一个普通的字符指针使用就可能在运行时发生错误。如:

string str(pc);

可能导致异常的运行时行为。

如上列子所时,使用 reintertpret_cast 是非常危险的,应该尽量避免使用。

 

强制类型转换干扰了正常的类型检查,很容易出错,应尽量避免使用。

 

旧式的强制类型转换:

type(expr);//函数形式的强制类型转换

(type) expr;//c语言风格的强制类型转换

根据所涉及的类型不同,旧式的强制类型转换分别具有与 const_cast, static_cast 或 reinterpret_cast 相似的行为。当我们在某处执行旧式强制类型转换时,如果换成 const_cast 和 static_cast 也合法,则其行为与对应的命名转换一致。如果换后不合法,则旧式强制类型转换执行与 reinterpret_cast 类似的功能:

int *ip;

char *pc = (char*) ip;

效果与使用 reinterpret_cast 一样。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          

posted @ 2017-12-02 19:08  geloutingyu  阅读(256)  评论(0编辑  收藏  举报