ITPub博客

首页 > Linux操作系统 > Linux操作系统 > [原]reinterpret_cast强制转换与类的虚拟表

[原]reinterpret_cast强制转换与类的虚拟表

原创 Linux操作系统 作者:zuohongyoulan 时间:2008-09-25 15:49:28 0 删除 编辑


测试平台为:windowsxp,vs2003
先看一下一个简单的例子

#include
using namespace std;

int main()
{ 
  char *p = "aabbccdd";
  int *i = reinterpret_cast (p); // cast pointer to integer
  cout<<"i="<<*i<  cout<<"i+1="<<*(i+1)<  return 0;
}
打印结果为:
i=1650614625
i+1=1684300643
转化为十六进制为
i=62626161     //顺序为bbaa
i+1=64646363   //顺序为ddcc
由于windowxp平台是Big-Endian,所以与"aabbccdd"刚好吻合


reinterpret_cast是最不安全的转换机制,很有可能产生bugs, 转换时不会考虑数据本身的内容,只做类型的转换。

#include "stdafx.h"
#include
using namespace std;

class Parent
{
public:
 virtual void printTest()
  {
   cout<<"Parent print"<  }
};

class Child1 :public Parent
{
public :
  void printTest()
 {
  cout<<"Child1 print"<   printTest1();
 }

  void printTest1()
 {
  cout<<"Child1 printTest1"< }
};

class Child2 :public Parent
{
public :
  void printTest()
 {
  cout<<"Child2 print"<   printTest1();
 }
  void printTest1()
 {
  cout<<"Child2 printTest1"< }
};

int _tmain(int argc, _TCHAR* argv[])
{
 Child1 *p = new Child1();
 p->printTest();
        Child2* pC2 = reinterpret_cast(p);
        pC2->printTest();
 pC2->printTest1();
 cout<<"Child1 Size="< cout<<"Child2 Size="< delete p;
 return 0;
}

打印结果为:
Child1 print
Child1 print
Child2 printTest1
Child1 Size=4
Child2 Size=4

由于Parent类printTest函数为virtual, 所以Child1 和Child2的printTest函数都也为virtual
Parent类存在虚拟表,Child1 和Child2没有虚拟表,当发生reinterpret_cast强制转换的时候,
在Parent类虚拟表中的Child1::printTest(void)函数直接转换过来。

如果Parent类的printTest函数为普通函数,Child1 和Child2的printTest函数都为virtual函数
打印结果也是:
Child1 print
Child1 print
Child2 printTest1
Child1 Size=4
Child2 Size=4
这时候Parent类中没有虚拟表,Child1 和Child2有虚拟表,在Child1类虚拟表中的Child1::printTest(void)函数转换
到pC2对象中。同样也会调用Child1::printTest(void)函数。


如果Parent类的printTest函数为普通函数,Child1的printTest函数都为virtual函数,Child2的printTest函数都为普通函数,
打印结果是:
Child1 print
Child2 print
Child2 printTest1
Child1 Size=4
Child2 Size=1
这时候Parent类中没有虚拟表,Child1有虚拟表,Child2没有虚拟表,Child2的内存大小没有Child1大,所以输出了Child2 print

如果Parent类的printTest函数为普通函数,Child1的printTest函数都为普通函数,Child2的printTest函数都为virtual函数,
程序运行出错,这时候Parent类中没有虚拟表,Child1没有虚拟表,Child2有虚拟表,Child2的内存大小比Child1大,
Child2中的虚拟表值为非法,所以运行出错。


如果Parent类的printTest函数为普通函数,Child1的printTest函数都为普通函数,Child2的printTest函数都为virtual函数,
而且Child1的printTest1函数都为virtual函数,Child2的printTest1函数都为普通函数,
打印结果是:
Child1 print
Child1 printTest1
Child2 printTest1
Child1 Size=4
Child2 Size=4
这时候Parent类中没有虚拟表,Child1有虚拟表,Child2有虚拟表,本想打印出Child2 print,结果打印出Child1 printTest1。
这就是所谓的严重bug,因为reinterpret_cast只是做表面上的类型转换,数据没有发生变化,在Child2的虚拟表中还是指向
Child1::printTest2(void)函数,而不是Child2::print(void)函数

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/12925485/viewspace-464338/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2008-09-18

  • 博文量
    24
  • 访问量
    44058