强转 static_cast dynamic_cast reinterpret_cast 疑难杂症
2016-07-27 18:28
316 查看
总结了一些疑问,<span style="color:#ff0000;">如果有什么错误,还望大家指正~</span> 1.static_cast和强转有什么区别? (1)相同:首先都是在编译时完成 (2)区别:前者更安全,如: class A{} class B{} [1]A* pA = (A*)new B;-----编译通过 [2]A* pA = static_cast<A*>(new B)编译失败 2.为什么不是所有static_cast都可以用dynamic_cast代替? (1)效率问题 (2)某些情况编译问题,如: class A{} class B : public A{} A* pA = new B; [1]B* pB = static_cast<B*>(pA);-----编译通过 [2]B* pB = dynamic_cast<B*>(pA);-----编译失败 其实这里是因为dynamic_cast更牛逼导致的,至于原因,我们看问题3. 3.为什么问题2.的dynamic_cast编译不过? (1)编译报错:dynamic_cast的操作数必须包含多态类类型 (2)这是因为编译器实现虚函数考的是虚函数表(Vtable),如果没有虚函数存在,编译器没有必要浪费空间 实现一个虚指针 (3)所以这里如果想让编译通过,在A中添加一个虚函数ok了,如: class A { virtual void f() } 注:这里补充一下虚表和虚指针的知识: [1]虚表:存在虚函数的类都有一个一维的虚函数表 [2]虚指针:类的对象有一个指向虚表开始的虚指针 [3]虚表和类对应,虚指针和对象对应 4.什么情况只能用dynamic_cast而不能用static_cast? (1)看代码:把A转成兄弟B,就不能用static_cast class A { virtual void f(){} } class B {} class C : public A, public B A* pA = new C; [1]B* pB = static_cast<B*>(pA);-----编译失败:类型转换无效 [2]B* pB = dynamic_cast<B*>(pA);-----编译通过 5.reinterpret_cast (1)字面意思:interpret:解释、诠释;reinterpret:重新解释 (2)reinterpret_cast<type-id> (expression): [1]百度百科:type-id必须是一个指针、引用、算数类型、函数指针或者成员指针。它可以把一个指针转换成一个 整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,再把该证书转换成原类型的指针 ,还可以得到原先的指针值) [2]为什么type-id要做如此限制?看代码: char* str = "aTTTbT"; int* pA = reinterpret_cast<int*>(str); printf("%d\n", *(++pA)); // 21602 = "bT"的二进制转成int = 'T' * 256 + 'b'; printf("%d-%d\n", pA, str); // "19257864-19257864" : 同一内存块 这说明reinterpret_cast的作用只是把同一块内存代码诠释成不同的类型罢了,挺危险的。。。 [3]然后再来看看与static_cast的区别 class A {int m_a; int m_aa;} class B {int m_b;} class C : public A, public B {} C c; printf("%p, %p, %p", &c, reinterpret_cast<B*>(&c), static_cast <B*>(&c)); // 结果 = “004FFB68, 004FFB68, 004FFB70” 这是因为static_cast计算父子类指针的偏移量,并将之转换到正确地址(偏移了两个int:m_a, m_aa), 而reinterpret_cast并没有这样做,而是保持内容不变 [4]什么时候用到reinterpret_cast? 我只知道一种,还是百度出来的: “最普通的用途就是在函数指针类型之间进行转换” int doSomething(){return 0;}; typedef void(*FuncPtr)(); FuncPtr funcPtrArray[10]; [4-1]funcPtrArray[0] = &doSomething;-----编译失败:返回值类型不匹配 [4-2]funcPtrArray[0] = reinterpret_cast<FuncPtr>(&doSomething);-----编译通过 <span style="background-color: rgb(255, 204, 204);"><span style="color:#ff0000;">如果大家还知道有什么用处,请多多指教~</span></span>
相关文章推荐
- R 绘图系统
- 【iOS开发】iOS移动端架构
- 怎样写好求职简历(STAR法则)及成为优秀的工程师 及职业历程
- 情感分析
- 【分类】朴素贝叶斯算法学习
- 驱动相关Error
- 第三方Charts绘制图表四种形式:饼状图,雷达图,柱状图,直线图
- python requests 模拟网站登录
- 第三方Charts绘制图表四种形式:饼状图,雷达图,柱状图,直线图
- python 购物流程脚本
- minerd木马处理流程
- 可以ping通,但无法通过ssh连接虚拟机的解决方案
- validates的条件验证(if)的Proc用法
- ubuntu14.04下安装QT4,QT5
- sudo 出现unable to resolve host 解决方法
- HTML 颜色速查表
- awstats 分析nginx 日志
- matlab灰度变彩色+白平衡算法实现
- 2016.07.15【初中部 NOIP提高组 】模拟赛C
- POJ 1011 STICKS 搜索 剪枝