更新中.....
建议:避免强制类型转换 尤其是reinterpret_cast
显示转换:
命名的强制类型转换:一个命名的强制类型转换具有以下形式:cast-name<type>(expression)
其中type是转换的目标类型,expression是要转换的值,如果type是引用类型,则结果是左值,cast-name是static_cast,dynamic_cast,const_cast和reinterpret_cast中的一种。其中dynamic_cast支持运行时类型识别。cast-name说明了是哪种类型转换。
static_cast:
- 任何一个具有明确定义的类型转换,只要不包含底层const,都可以使用static_cast,例如,通过一个整型运算对象强制转换成doulbe类型就可以使表达式执行浮点数除法。
int i,j;
double slope=i/j;
double slope=static_cast<double>(j)/i;
- 一般来说,当编译器发现将一个较大的算数类型试图赋值给较小的类型,就会给出警告信息,但是如果执行静态类型转换,警告就会消失。
- 当我们把指针存放在void*中,并且使用static_cast将其强制类型转换回原来的类型时,应该确保指针的值保持不变,强制类型转换的结果和原始的地址值相等,类型一旦不符,就会产生未定义的结果。
const_cast:
- const_cast只能改变运算对象底层const,对于将常量对象转换成非常量对象的行为,一般称为去掉const性质(cast away the const),一般去掉了某个对象的const性质,编译器就不再阻止我们对该对象进行读写操作了,如果对象本身不是一个常量,使用强制类型转换获取写权限是合法行为。如果对象是一个常量,再使用const_cast进行写操作就会产生其它未定义的结果。只有
const char *pc;
chat *p=const_cast<char*>(pc);
- const_cast能够改变表达式的常量属性,使用其他形式的命名强制类型转换改变表达式的常量属性都将引发编译器错误。
- const_cast常常用于有函数重载的上下文中。
const_cast和重载
- 下列程序中两个stringshouter()函数是重载函数,当传入实参类型是常量类型时,函数返回值也是常量类型,传入实参是非常量时,函数返回类型是非常量。
#include<cstdio>
#include<string>
#include<iostream>
using namespace std;
//该函数的形参是对const string 的引用
//返回类型是const string&
const string &stringshouter(const string &s1, const string &s2)
{
return s1.size() > s2.size() ? s2: s1;
}
//该函数的形参和返回类型都是对非常量string的引用
string& stringshouter(string &s1, string &s2)
{
//auto初始化表达式是引用时,会去除&,因此这里要带上&符号
auto &r=stringshouter(const_cast<const string&>(s1), const_cast<const string&>(s2));
//去除r的const属性;
return const_cast<string&>(r);
}
int main()
{
const string s1 = "hello world"; const string s2 = "hello";
auto &s = stringshouter(s1, s2);
cout << s << endl;
string s3 = "I'm beautiful"; string s4 = "I'm cute";
auto w= stringshouter(s3, s4);
cout << w << endl;
return 0;
}
reinterpret_cast:
dynamic_cast: