首页 > 学院 > 开发设计 > 正文

菱形继承与虚拟菱形继承对象模型

2019-11-08 03:13:22
字体:
来源:转载
供稿:网友

菱形继承对象模型

下面用一段菱形继承的代码来探究菱形继承的对象模型

class AA{public: virtual void fun1() { cout << "AA::fun1()" << endl; }public: int _a;};class BB : public AA{public: virtual void fun1() { cout << "BB::fun1()" << endl; }public: int _b;};class CC : public AA{public: virtual void fun1() { cout << "CC::fun1()" << endl; }public: int _c;};class DD :public BB,public CC{public: virtual void fun1() { cout << "DD::fun1()" << endl; } virtual void fun2() { cout << "DD::fun2()" << endl; }public: int _d;};void Test1(){ DD d; d.BB::_a = 1; d.CC::_a = 2; d._b = 3; d._c = 4; d._d = 5;}

打开内存窗口,进行单步调试,结果如下: 这里写图片描述 这里写图片描述 对于对象d,重写了fun1(),所以将DD的fun1()放入虚表,再将fun2()放入虚表,图片中另一个虚表指针指向的是CC中的虚函数,CC中的fun1()重写了AA中的fun1(),所以在虚表中放入CC的fun1()。这一这样理解,橙色区域本来应给是AA类,续表中存储的是AA::fun1()的地址,但是BB类中从写了fun1(),所以把AA::fun1()替换为了CC::fun1()。所以,对于一个类中的虚函数,若是重写的父类的,则将虚表中的函数地址替换为自己的虚函数地址,若不是重写的函数,则直接将该函数地址放入虚表中。

菱形虚拟继承对象模型

现在把上面的代码改为虚拟继承,再来看内存窗口中的结果: 这里写图片描述 这里写图片描述 下面提供完整的代码调用虚函数

class AA{public: virtual void fun1() { cout << "AA::fun1()" << endl; }public: int _a;};class BB : virtual public AA{public: virtual void fun1() { cout << "BB::fun1()" << endl; }public: int _b;};class CC : virtual public AA{public: virtual void fun1() { cout << "CC::fun1()" << endl; }public: int _c;};class DD :public BB,public CC{public: virtual void fun1() { cout << "DD::fun1()" << endl; } virtual void fun2() { cout << "DD::fun2()" << endl; }public: int _d;};typedef void(*FUNC) ();void PRintfVTable(int *VTable){ cout << "虚表地址:" << "0x" << VTable << endl; for (int i = 0; VTable[i] != 0; ++i) { cout << "虚函数地址:0x" << VTable[i] << " "; FUNC f = (FUNC)VTable[i]; f(); } cout << endl;}void Test1(){ DD d; d.BB::_a = 1; d.CC::_a = 2; d._b = 3; d._c = 4; d._d = 5; int* VTable = (int *)(*(int *)&d); PrintfVTable(VTable); VTable = (int *)(*((int*)&d + 6)); PrintfVTable(VTable);}

这里写图片描述


上一篇:Crackme 1

下一篇:RCP中showView方法的说明

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表