强转 static_cast dynamic_cast reinterpret_cast 疑难杂症

来源:互联网 发布:折半查找算法过程 编辑:程序博客网 时间:2024/06/13 13:51
总结了一些疑问,<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_castclass A { virtual void f(){} }class B {}class C : public A, public BA* 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>

0 0
原创粉丝点击