深入C++对象模型&虚函数表
多态的实现机制:
C++中虚函数的主要作用就是用来实现多态,就是使用基类的指针或者引用调用重写的虚函数,当父类的指针或引用指向父类对象时调用的是父类虚函数,当指向子类对象时调用的是子类的虚函数。那么这又是怎么实现的呢???
这都是通过虚函数表实现的,虚函数表是通过一块连续内存来存储虚函数的地址。这张表解决了虚函数重写(地址进行覆盖)的问题 。在有虚函数的对象实例中都有一张虚函数表,虚函数表就像一张地图,指明了实际调用的虚函数函数。
例:
classBase{public:Base():_b(1){}virtualvoidfun1(){}virtualvoidfun2(){}private:int_b;};
虚函数表的最后一个元素是一个空指针。
既然我们知道了虚函数的地址,那么就可以通过过找到这块地址来调用这个虚函数。这也导致了多态的不安全性,效率降低。
typedefvoid(*pfun)();voidPrintfBase(pfun*_ppfun){inti=0;for(i=0;_ppfun[i]!=NULL;i++){_ppfun[i]();}}voidtest(){Baseb;PrintfBase((pfun*)*((int*)(&b)));}
1、单继承对象模型
classBase{public:Base():_b(1){}virtualvoidfun1(){cout<<"Base::fun1()"<<endl;}virtualvoidfun2(){cout<<"Base::fun2()"<<endl;}private:int_b;};classDeriver:publicBase{public:Deriver():_d(2){}virtualvoidfun1(){cout<<"Deriver::fun1()"<<endl;}virtualvoidfun3(){cout<<"Deriver::fun3()"<<endl;}private:int_d;};typedefvoid(*pfun)();voidPrintfBase(pfun*_ppfun){inti=0;for(i=0;_ppfun[i]!=NULL;i++){_ppfun[i]();}}voidtest(){Baseb;PrintfBase((pfun*)*((int*)(&b)));}
2、多重继承的对象模型
classBase1{public:Base1():_b1(1){}virtualvoidfun1(){cout<<"Base1::fun1()"<<endl;}virtualvoidfun2(){cout<<"Base1::fun2()"<<endl;}private:int_b1;};classBase2{public:Base2():_b2(2){}virtualvoidfun1(){cout<<"Base2::fun1()"<<endl;}virtualvoidfun2(){cout<<"Base1::fun2()"<<endl;}private:int_b2;};classDeriver:publicBase1,publicBase2{public:Deriver():_d3(3){}virtualvoidfun1(){cout<<"Deriver::fun1()"<<endl;}virtualvoidfun3(){cout<<"Deriver::fun3()"<<endl;}private:int_d3;};
3、菱形继承的对象模型
classBase{public:Base():_b1(1){}virtualvoidfun1(){cout<<"Base1::fun1()"<<endl;}virtualvoidfun2(){cout<<"Base1::fun2()"<<endl;}private:int_b1;};classBase2:publicBase{public:Base2():_b2(1){}virtualvoidfun1(){cout<<"Base2::fun1()"<<endl;}virtualvoidfun3(){cout<<"Base2::fun2()"<<endl;}private:int_b2;};classBase3:publicBase{public:Base3():_b3(1){}virtualvoidfun1(){cout<<"Base3::fun1()"<<endl;}virtualvoidfun3(){cout<<"Base3::fun2()"<<endl;}private:int_b3;};classDeriver:publicBase2,publicBase3{public:Deriver():_d3(3){}virtualvoidfun1(){cout<<"Deriver::fun1()"<<endl;}virtualvoidfun4(){cout<<"Deriver::fun3()"<<endl;}private:int_d3;};
4、菱形的虚拟继承
<span>classBase{public:Base():_b1(1){}virtualvoidfun1(){cout<<"Base1::fun1()"<<endl;}virtualvoidfun2(){cout<<"Base1::fun2()"<<endl;}private:int_b1;};classBase2:virtualpublicBase{public:Base2():_b2(2){}virtualvoidfun1(){cout<<"Base2::fun1()"<<endl;}virtualvoidfun3(){cout<<"Base2::fun2()"<<endl;}private:int_b2;};classBase3:virtualpublicBase{public:Base3():_b4(3){}virtualvoidfun1(){cout<<"Base3::fun1()"<<endl;}virtualvoidfun3(){cout<<"Base3::fun2()"<<endl;}private:int_b3;};classDeriver:publicBase2,publicBase3{public:Deriver():_d3(4){}virtualvoidfun1(){cout<<"Deriver::fun1()"<<endl;}virtualvoidfun4(){cout<<"Deriver::fun4()"<<endl;}private:int_d4;};</span>
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。