细谈C++多态性的“动”与“静”

出处:Examlink 作者: 日期:2008年03月20日 13时56分

根据上述的汇编代码,我们可以知道,在多态调用函数的时候,程序执行以下步骤:

  1、寻址找到pObj1

  2、由于C11重载了Test虚函数,所以*pObj1指向的就是C11的VTable的地址

  3、调用pObj1->Test()时,程序通过Vptr(虚表的指针,对象的首地址),找到VTable,再根据偏移调用Test函数。

  由于上述的多态调用过程是一个动态的过程(在运行时去“找”函数来调用),而不是编译完就直接把函数地址摆在那里了,所以被称作“动态联编”。

  上面把多态的“动”和“静”的特点结合代码说了一遍,希望能说清楚了。

  下面再验证一个类的虚表的问题,如果你对虚表已经很熟悉了,就不用再往下看了。

  在很多书上都已经说明了C++的对象模型,这里只是做个验证。看看这段代码:

class C1
...{
public:
virtual void Test()
...{
cout << "call C1 Test()" << endl;
}
};

class C11 : public C1
...{
public:
void Test()
...{
cout << "call C11 Test()" << endl;
}
};

class C12 : public C1
...{
public:
void Test()
...{
cout << "call C12 Test()" << endl;
}
};

  我们可以知道 Test() 是虚函数,从C1派生的类必定有自己的虚表。而且根据别的资料,虚表指针是放在对象的首地址的,我们下面就来验证一下:Examlink

// 验证首地址
C11 obj110;
C11 obj111;

printf("obj110 的地址:%x ", &obj110);
printf("obj111 的地址:%x ", &obj111);
printf("obj110 虚表的地址:%x ", *(&obj110));
printf("obj111 虚表的地址:%x ", *(&obj111));

  结果是:

  obj110 的地址:12ff7c
  obj111 的地址:12ff78
  obj110 虚表的地址:432098
  obj111 虚表的地址:432098

  由上面的结果我们可以验证:

  1、一个类一个VTABLE,而不是一个对象一个VTABLE。

  2、对象的首地址的内容就是VTABLE的地址。

  总结一下:

  C++的多态性包括其概念和实现,本文从编译器生成的代码来讨论C++多态特性,特别说明了为什么多态特性被称为“动态联编”,它和“静态联编”有什么不同,它们的“动”与“静”体现在哪里。另外还对对象的虚表做了些验证。好了,希望本文能对你认识C++的多态性有一定的帮助!

最后更新时间:2008-03-28 14:25:35
共2页: 上一页 [1] 2 下一页
文章评论
共有 0 位网友发表了评论
用户名: 新注册) 密码: 匿名评论 [查看所有评论]

评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
您可以用以下几种方式找到此文章

考试全流程