4-11.3 C++中的显式类转换
2022/1/18 12:34:31
本文主要是介绍4-11.3 C++中的显式类转换,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
目录- static_cast
- 1.用来改变基本类型:一般是高精度转低精度
- 2.恢复void* 指针类型
- const_cast
- 用来去除底层const(low-level const)
- reinterpret_cast
- 旧式类型转换
static_cast
1.用来改变基本类型:一般是高精度转低精度
显示地告诉程序阅读者和编译器,不考虑高精度想低精度转换时造成的精度损失
#include<iostream> using namespace std; int main(){ double d = 2.1; int i = 6; int res = i/d; //i被隐式地转换为double res=6/2.1 = 2 cout<<res<<endl; //输出2 res = i/static_cast<int>(d); //d被强制转换为int res = 6/2 = 3 cout<<res<<endl; //输出3 return 0; }
2.恢复void* 指针类型
#include<iostream> using namespace std; int main(){ int i = 2; void *p = &i; //无法通过p得到它所指对象的值 int *q = static_cast<int*>(p); //将其转换为int*,得到其所指向的值 cout<<*q<<endl; //输出2 return 0; }
注意:void*在强制类型转换时只能转换为原来的对应类型,如例子中,只能转换为int*,否则会产生未定义行为
const_cast
用来去除底层const(low-level const)
#include<iostream> using namespace std; int main(){ const char *pc; char *p = const_cast<char*>(pc); //把pc的底层const去除,否则无法对p进行初始化(p不是const) int *ip = static_cast<int*>( const_cast<char*>(pc)); //去除const后再改变基本类型 return 0; }
注:1.const_cast可以去除底层const,但不代表转换后的指针可以改变其指向的值,如果*p是一个const对象,依然不能用p改变其值。
2.const_cast只能去除const,不能改变对象的原类型,const_cast<string>(pc);
是不行的,改用static_const<string>(pc);
。
const_cast在函数重载时运用广泛
reinterpret_cast
为运算对象的位模式提供较低层次的重新解释,但并不真正改变对象类型
#include<iostream> using namespace std; int main(){ int *ip; char *pc = reinterpret_cast<char*>(ip); //pc所指的真实对象实际上是int类型而不是字符 string s(pc); //用int*来初始化string显然会出现问题,但由于有显示类型转换,所以编译器不会报错 cout<<s<<endl; return 0; }
使用reinterpret_cast是非常危险的,用pc初始化str的例子很好地证明了这一点。其中的关键问题是类型改变了,但编译器没有给出任何警告或者错误的提示信息。当我们用一个int的地址初始化pc时,由于显式地声称这种转换合法,所以编译器不会发出任何警告或错误信息。接下来再使用pc时就会认定它的值是char*类型,编译器没法知道它实际存放的是指向int的指针。最终的结果就是,在上面的例子中虽然用pc初始化 str 没什么实际意义,甚至还可能引发更糟糕的后果,但仅从语法上而言这种操作无可指摘。查找这类问题的原因非常困难,如果将ip 强制转换成pc的语句和用pc初始化 string对象的语句分属不同文件就更是如此。
所以在编程时经历避免强制类型转换
旧式类型转换
(type)expr
:c语言风格的函数类型转换,其含义并不清晰,根据语境会分别具有static\_cast
、const\_cast
、reinterpret\_cast
的功能。
int *ip; char *pc = (char*)ip; //作用同reinterpret_cast
所以追踪错误时会更加困难,不建议使用。
这篇关于4-11.3 C++中的显式类转换的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享