多重继承下的虚函数表

多重继承下的虚函数表

ID:1542418

大小:132.50 KB

页数:6页

时间:2017-11-12

多重继承下的虚函数表_第1页
多重继承下的虚函数表_第2页
多重继承下的虚函数表_第3页
多重继承下的虚函数表_第4页
多重继承下的虚函数表_第5页
资源描述:

《多重继承下的虚函数表》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库

1、多重继承下的虚函数表多态是C++语言中的一项重要的机制,虚函数就是为实现多态而设计的。多态就是用父类型的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。这种技术可以让父类的指针有“多种形态”。而虚函数表在这种多态机制中起了核心调度的作用。由于是编译器在后台操作,所以它被蒙上了一层神秘的面纱。    对C++了解的人都应该知道虚函数(VirtualFunction)是通过一张虚函数表(VirtualTable)来实现的。简称为VFTable。在这个表中,主要是一个类的虚函数的地址表,这张表解决了继承、覆盖的问题,保证其

2、容真实反应实际的函数。这样,在有虚函数的类的实例中这个表被分配在了这个实例的内存中,所以,当我们用父类的指针来操作一个子类的时候,VFTable就显得尤为重要了,它就像一个地图一样,指明了实际所应该调用的函数。在C++的标准中提到,编译器必需要保证虚函数表的指针存在于对象实例中最前面的位置。这意味着我们通过对象实例的地址得到它的VFTable,然后就可以遍历其中函数指针,并调用相应的函数。Code1:classBase{public:virtualvoidf(){cout<<"Base::f"<

3、(){cout<<"Base::g"<

4、(Fun)*((int*)*(int*)(&b));pFun();实际运行经果如下:(WindowsXP+VC6.0)虚函数表地址:0x00425030虚函数表—第一个函数地址:0040100FBase::f通过Code2看到,可以通过强行把&b转成int*,取得虚函数表的地址,然后,再次取址就可以得到第一个虚函数的地址了,也就是Base::f(),这在上面的程序中得到了验证(把int*强制转成了函数指针)。如此就可以知道如果要调用Base::g()和Base::h(),其代码如下:Code3:(Fun)*((int*)*(int*

5、)(&b)+0);//Base::f()(Fun)*((int*)*(int*)(&b)+1);//Base::g()(Fun)*((int*)*(int*)(&b)+2);//Base::h()通过类实例的偏移地址得到函数表地址,具体位置示意图如下:注意:在上面这个图中,虚函数表的最后多加了一个结点,它是虚函数表的结束结点,就像字符串的结束符“”一样,其标志了虚函数表的结束。这个结束标志的值在不同的编译器下是不同的。在WinXP+VC6.0下,这个值是NULL。下面,将分别说明“无覆盖”和“有覆盖”时的虚函数表的样子。没有覆盖

6、父类的虚函数是毫无意义的。无虚函数覆盖的一般继承如下所示的一个继承关系:注意,在这个继承关系中,子类没有重载任何父类的函数。那么,在派生类的实例中,其虚函数表如下所示:对于实例:Derived;的虚函数表如下:通过上图可以总结以下几点:1)虚函数按照其声明顺序放于表中。2)父类的虚函数在子类的虚函数前面。有虚函数覆盖的一般继承如下图所示:在这个类的设计中,只覆盖了父类的一个函数:f()。那么,对于派生类的实例,其虚函数表会是下面的一个样子:通过上图总结以下几点,1)覆盖的f()函数被放到了虚表中原来父类虚函数的位置。2)没有被覆盖的

7、函数依旧。Code4:Base*b=newDerive();b->f();由b所指的内存中的虚函数表的f()的位置已经被Derive::f()函数地址所取代,于是在实际调用发生时,是Derive::f()被调用了。这样就实现了多态性。无虚函数覆盖的多重继承,假设有下面这样一个类的继承关系。注意:子类并没有覆盖父类的函数。对于子类实例中的虚函数表,如下图所示:通过上面2图可以总结:1)每个父类都有自己的虚表。2)子类的成员函数被放到了第一个父类的表中。这样做就是为了解决不同的父类类型的指针指向同一个子类实例,而能够调用到实际的函数。有

8、虚函数覆盖的多重继承下图中,在子类中覆盖了父类的f()函数。下面是对于子类实例中的虚函数表的图:可以看出,三个父类虚函数表中的f()的位置被替换成了子类的函数指针。这样,我们就可以任一静态类型的父类来指向子类,并调用子类的f()了。如

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。