多态的实现机制:
C++中虚函数的主要作用就是用来实现多态,就是使用基类的指针或者引用调用重写的虚函数,当父类的指针或引用指向父类对象时调用的是父类虚函数,当指向子类对象时调用的是子类的虚函数。那么这又是怎么实现的呢???
这都是通过虚函数表实现的,虚函数表是通过一块连续内存来存储虚函数的地址。这张表解决了虚函数重写(地址进行覆盖)的问题 。在有虚函数的对象实例中都有一张虚函数表,虚函数表就像一张地图,指明了实际调用的虚函数函数。
例:
class Base { public: Base() :_b(1){} virtual void fun1() { } virtual void fun2() { } private: int _b; };
虚函数表的最后一个元素是一个空指针。
既然我们知道了虚函数的地址,那么就可以通过过找到这块地址来调用这个虚函数。这也导致了多态的不安全性,效率降低。
typedef void (* pfun)(); void PrintfBase(pfun *_ppfun) { int i = 0; for (i = 0; _ppfun[i] != NULL; i++) { _ppfun[i] (); } } void test() { Base b; PrintfBase((pfun *)*((int *)(&b))); }
1、单继承对象模型
class Base { public: Base() :_b(1){} virtual void fun1() { cout << "Base::fun1()" <<endl; } virtual void fun2() { cout << "Base::fun2()" << endl; } private: int _b; }; class Deriver :public Base { public: Deriver() :_d(2){} virtual void fun1() { cout << "Deriver::fun1()" << endl; } virtual void fun3() { cout << "Deriver::fun3()" << endl; } private: int _d; }; typedef void (* pfun)(); void PrintfBase(pfun *_ppfun) { int i = 0; for (i = 0; _ppfun[i] != NULL; i++) { _ppfun[i] (); } } void test() { Base b; PrintfBase((pfun *)*((int *)(&b))); }
2、多重继承的对象模型
class Base1 { public: Base1() :_b1(1){} virtual void fun1() { cout << "Base1::fun1()" <<endl; } virtual void fun2() { cout << "Base1::fun2()" << endl; } private: int _b1; }; class Base2 { public: Base2() :_b2(2){} virtual void fun1() { cout << "Base2::fun1()" << endl; } virtual void fun2() { cout << "Base1::fun2()" << endl; } private: int _b2; }; class Deriver :public Base1,public Base2 { public: Deriver() :_d3(3){} virtual void fun1() { cout << "Deriver::fun1()" << endl; } virtual void fun3() { cout << "Deriver::fun3()" << endl; } private: int _d3; };
3、菱形继承的对象模型
class Base { public: Base() :_b1(1){} virtual void fun1() { cout << "Base1::fun1()" << endl; } virtual void fun2() { cout << "Base1::fun2()" << endl; } private: int _b1; }; class Base2:public Base { public: Base2() :_b2(1){} virtual void fun1() { cout << "Base2::fun1()" << endl; } virtual void fun3() { cout << "Base2::fun2()" << endl; } private: int _b2; }; class Base3:public Base { public: Base3() :_b3(1){} virtual void fun1() { cout << "Base3::fun1()" << endl; } virtual void fun3() { cout << "Base3::fun2()" << endl; } private: int _b3; }; class Deriver:public Base2,public Base3 { public: Deriver() :_d3(3){} virtual void fun1() { cout << "Deriver::fun1()" << endl; } virtual void fun4() { cout << "Deriver::fun3()" << endl; } private: int _d3; };
4、菱形的虚拟继承
<span style="font-size:14px;">class Base { public: Base() :_b1(1){} virtual void fun1() { cout << "Base1::fun1()" << endl; } virtual void fun2() { cout << "Base1::fun2()" << endl; } private: int _b1; }; class Base2:virtual public Base { public: Base2() :_b2(2){} virtual void fun1() { cout << "Base2::fun1()" << endl; } virtual void fun3() { cout << "Base2::fun2()" << endl; } private: int _b2; }; class Base3:virtual public Base { public: Base3() :_b4(3){} virtual void fun1() { cout << "Base3::fun1()" << endl; } virtual void fun3() { cout << "Base3::fun2()" << endl; } private: int _b3; }; class Deriver:public Base2,public Base3 { public: Deriver() :_d3(4){} virtual void fun1() { cout << "Deriver::fun1()" << endl; } virtual void fun4() { cout << "Deriver::fun4()" << endl; } private: int _d4; };</span>
本文出自 “11132019” 博客,转载请与作者联系!
原文地址:http://11142019.blog.51cto.com/11132019/1846838