【c++知识归纳】继承与多态(二)

来源:互联网 发布:淘宝的无印良品都是假 编辑:程序博客网 时间:2024/05/16 06:43
在继承与多态(一)中简单介绍了继承与多态的基础知识,本文将从内存中深入理解c++的继承与多态。
本文我选用了较低版本的IDE:【windows 10】系统的vs2008,因为高版本的处理比较复杂,为了看的更清楚,我们选择这个较低版本的编译器。

1.虚函数表(虚表)
class Base{public:Base():_b(1){}virtual void fun(){cout << "Base::fun()" << endl;}protected:int _b;};<pre class="cpp" name="code">int main(){Base b;system("pause");return 0;}
调试上面的代码,打开监视和内存:
 
虚函数表:通过一块连续的内存来存储虚函数的地址。虚表指针指向这一块连续的空间。
2.单继承的对象模型
通过下面的代码来探索
class Base{public:Base():_b(1){}virtual void fun1(){cout << "Base::fun1()" << endl;}virtual void fun2(){cout << "Base::fun2()" << endl;}protected:int _b;};class Derive:public Base{public:Derive():_d(2){}virtual void fun1(){cout << "Derive::fun1()" << endl;}virtual void fun3(){cout << "Derive::fun3()" << endl;}protected:int _d;};typedef void(*pfun)();void PrintVfptr(pfun *ppfun)//调用虚表中的函数{for (int i = 0; ppfun[i] != NULL; i++){ppfun[i]();}}void test(){Derive d;PrintVfptr((pfun*)(*(int *)&d));}int main(){test();system("pause");return 0;}
同样,调试上面这段代码,打开内存和监视,来探索单继承子类对象在内存中的存储。
通过上面图片的分析,可以看到,当子类重写了父类的虚函数后,子类的函数地址直接将父类原来的函数地址覆盖,即虚表中的函数地址已经改为子类的函数地址了。所以当我们用父类的指针指向子类的对象时,调用的是子类重写的虚函数,这样就实现了多态。

3.多重继承的对象模型
class Base1{public:Base1():_b1(1){}virtual void fun(){cout << "Base1::fun()" << endl;}virtual void fun1(){cout << "Base1::fun1()" << endl;}protected:int _b1;};class Base2{public:Base2():_b2(2){}virtual void fun(){cout << "Base2::fun()" << endl;}virtual void fun2(){cout << "Base2::fun2()" << endl;}protected:int _b2;};class Derive :public Base1, public Base2{public:Derive():_d(3){}virtual void fun(){cout << "Derive::fun()" << endl;}virtual void fun2(){cout << "Derive::fun1()" << endl;}virtual void fun3(){cout << "Derive::fun3()" << endl;}protected:int _d;};typedef void(*pfun)();void PrintVfptr(pfun* ppfun){for (int i = 0; ppfun[i] != NULL; i++){ppfun[i]();}}void test(){Derive d;printf("第1个虚表\n");PrintVfptr((pfun*)(*(int*)&d));printf("第2个虚表\n");PrintVfptr((pfun*)(*((int*)&d+2)));}int main(){test();system("pause");return 0;}
通过上图的分析,可以总结如下规律:
(1)有n个基类,则派生类就有n个虚表指针,也就有n个虚表。
(2)多重继承最左端的基类,它的虚表为主要表格,其中包含着Derive类的多有虚函数。


0 0
原创粉丝点击