研究虚表(探索多态的原理)和菱形虚拟继承

来源:互联网 发布:java修改全局变量 编辑:程序博客网 时间:2024/05/20 21:23


多态——  一个接口 多种形态,


编译器在执行过程中遇到virtual关键字的时候,将自动安装动态联编需要的机制,首先为这些包含virtual函数的类(注意不是类的实例)--即使是祖先类包含虚函数而本身没有--建立一张虚拟函数表VTABLE。在这些虚拟函数表中,编译器将依次按照函数声明次序放置类的特定虚函数的地址。同时在每个带有虚函数的类中放置一个称之为vpointer的指针,简称vptr,这个指针指向这个类的VTABLE。


一般来说一个对象的大小为所有成员变量的大小,但是当存在虚函数的时候即使这个类没有任何成员变量,他的对象的大小也不为0,为一个虚函数指针的大小。
当定义父类的一个函数为虚函数时,在子类中重载这个函数,用一个父类指针指向子类对象,并调用该函数的时候,调用的是子类的函数而不是父类的。如果搜索

父类中这个函数不是虚函数的话,调用的就是父类的函数了


菱形继承

#include<iostream>using namespace std;class AA{public:int _aa;};class BB : public AA{public:int _bb;};class  CC : public AA{public:int _cc;};class DD :public BB, public CC{public:int _dd;};int main(){ DD d;d.BB::_aa = 0;d.CC::_aa = 1;d._bb = 2;d._cc = 3;d._dd = 4;cout<< sizeof(d) << endl;return 0;}

  我们能够看到对象d中有继承的类BB和类CC,我们能够看到菱形继承中,对象d中存在两个成员_aa,这就存在问题,当我们想要访问_a时,编译器也不会知道我们想要访问的是哪一个变量,这就说明菱形继承存在一个“数据冗余”和“二义性“的问题。那么如何解决菱形继承所存在的这种问题呢


菱形虚拟继承

#include<iostream>using namespace std;class AA{public:int _aa;};class BB :virtual public AA{public:int _bb;};class  CC :virtual public AA{public:int _cc;};class DD :public BB, public CC{public:int _dd;};int main(){ DD d;d.BB::_aa = 0;d.CC::_aa = 1;d._bb = 2;d._cc = 3;d._dd = 4;cout<< sizeof(d) << endl;return 0;}

虚拟继承解决了这些问题  

0 0
原创粉丝点击