I. Polymorphic implementations--Virtual tables
I. polymorphic Concepts & Virtual Tables
1. Polymorphism is a variety of forms. In C + +, the same instruction is issued for different objects constructed by the same parent class and subclass, requiring them to do different work, it is necessary to write a function method of the same function name in the parent class and subclass, and distinguish them with virtual function . The pointer/reference of the parent class invokes the overridden virtual function, which is called when the parent class pointer/reference points to the parent class object, and the virtual function of the child class is called when the child class object is pointed to.
2. A virtual function table is an address that stores virtual functions through a contiguous memory . This table solves the problem of inheritance, virtual functions (Overrides). There is a virtual function table in an object instance with a virtual function, and a virtual function table is like a map that indicates the virtual function function that should be called actually.
Classes with virtual functions class base{public:virtual void Func1 () {cout << "base::func1 ()" << Endl; } virtual void Func2 () {cout << "base::func2 ()" << Endl; }private:int A;}; void Test1 () {Base B1;}
3. Model structure of a class with virtual functions
650) this.width=650; "src=" Http://s5.51cto.com/wyfs02/M00/7F/31/wKiom1cWE-ygeEwUAABjrK6s0Sc449.png "title=" capture. PNG "alt=" Wkiom1cwe-ygeewuaabjrk6s0sc449.png "/>
4. Share the same virtual table with objects of the same class
void Test2 () {Base B1, B2, B3;}
650) this.width=650; "src=" Http://s4.51cto.com/wyfs02/M00/7F/31/wKiom1cWFljzazxHAABRLNDV3ww863.png "title=" Capture 1. PNG "alt=" Wkiom1cwfljzazxhaabrlndv3ww863.png "/>
Two. Single-Inheritance & multiple-Inheritance object model
1. Single Inheritance:
CLASS&NBSP;BASE{PUBLIC:&NBSP;&NBSP;&NBSP;&NBSP;VIRTUAL&NBSP;VOID&NBSP;FUNC1 () { cout << "Base::func1 ()" << endl; &NBSP;&NBSP;&NBSP;&NBSP;}&NBSP;&NBSP;&NBSP;&NBSP;VIRTUAL&NBSP;VOID&NBSP;FUNC2 () { cout << "Base::func2 ()" << endl; }private: int a;}; class derive :p ublic base{public: virtual void func1 () { cout << "Derive::func1" &NBSP;<<&NBSP;ENDL;&NBSP;&NBSP;&NBSP;&NBSP;}&NBSP;&NBSP;&NBSP;&NBSP;VIRTUAL&NBSP;VOID&NBSP;FUNC3 () { cout << "Derive::func3" << endl; } &nBsp;virtual void func4 () { cout << "Derive::func4" << endl; }private: int b;}; Typedef void (*func) () void printvtable (int* vtable) { cout << " Virtual table address >" << vtable << endl; for (int i = 0; vtable[i] != 0; ++i) { printf (" %d virtual function address :0X%x,->", i, vtable[i]); FUNC f = (FUNC) vtable[i]; f (); } cout << endl;} Void test1 () { base b1; derive d1; int* VTable1 = (int*) (* (int*) &b1) int* vtable2 = (int*) (* (int*) &d1) printvtable (VTable1); printvtable ( VTable2);}
650) this.width=650; "src=" Http://s2.51cto.com/wyfs02/M02/7F/32/wKiom1cWLouis8NaAACxawvGyeo535.png "title=" Capture 3. PNG "alt=" Wkiom1cwlouis8naaacxawvgyeo535.png "/>
2. Multiple inheritance
CLASS&NBSP;BASE1{PUBLIC:&NBSP;&NBSP;&NBSP;&NBSP;VIRTUAL&NBSP;VOID&NBSP;FUNC1 () { cout << "Base1::func1" << endl; &NBSP;&NBSP;&NBSP;&NBSP;}&NBSP;&NBSP;&NBSP;&NBSP;VIRTUAL&NBSP;VOID&NBSP;FUNC2 () { cout << "Base1::func2" << endl; }private: int b1;}; CLASS&NBSP;BASE2{PUBLIC:&NBSP;&NBSP;&NBSP;&NBSP;VIRTUAL&NBSP;VOID&NBSP;FUNC1 () { cout << "Base2::func1" << endl; &NBSP;&NBSP;&NBSP;&NBSP;}&NBSP;&NBSP;&NBSP;&NBSP;VIRTUAL&NBSP;VOID&NBSP;FUNC2 () { cout << "Base2::func2" << endl; }private: int b2;};Class derive : public base1, public base2{public: virtual &NBSP;VOID&NBSP;FUNC1 () { cout < < "Derive::func1" << endl; } virtual &NBSP;VOID&NBSP;FUNC3 () { cout < < "Derive::func3" << endl; }private: int d1;}; Typedef void (*func) () void printvtable (int* vtable) { cout << " Virtual table address >" << vtable << endl; for (int i = 0; vtable[i] != 0; ++i) { printf (" %d virtual function address :0X%x,->", i, vtable[i]); func f = (FUNC) vtable[i]; f (); } cout << endl;} Void test1 () { derive d1; int* vtable = (int*) (* (int*) &d1); printvtable (VTable); // The BASE2 virtual function table is behind the object Base1 VTable = (int *) (* (int*) &d1 + sizeof ( BASE1) ( / 4)); printvtable (VTable);}
650) this.width=650; "src=" Http://s4.51cto.com/wyfs02/M01/7F/32/wKiom1cWMrPw5w-RAADE2gLhrO8811.png "title=" Capture 4. PNG "alt=" Wkiom1cwmrpw5w-raade2glhro8811.png "/>
Three. Static polymorphism and dynamic polymorphism
1. Static polymorphism is overloaded , because it is determined in the compile-time resolution , so called static polymorphism.
2. Dynamic polymorphism is the polymorphism implemented by inheriting the virtual function of the base class, because it is determined at runtime , so it is called dynamic polymorphism.
CLASS&NBSP;BASE{PUBLIC:&NBSP;&NBSP;&NBSP;&NBSP;VIRTUAL&NBSP;VOID&NBSP;FUNC1 () { cout << "Base::func1" << endl; &NBSP;&NBSP;&NBSP;}&NBSP;&NBSP;&NBSP;&NBSP;VIRTUAL&NBSP;VOID&NBSP;FUNC2 () { cout << "Base::func2" << endl; } void display () { cout << "Display ()" &NBSP;<<&NBSP;ENDL;&NBSP;&NBSP;&NBSP;&NBSP;} void display (int i) { cout << display (int i) << i << endl; }private: int a;}; class derive :p UBLIC&NBSP;BASE{PUBLIC:&NBSP;&NBSP;&NBSP;&NBSP;VIRTUAL&NBSP;VOID&NBSP;FUNC1 () { cout << "Derive::func1" << endl; } &NBSP;&NBSP;&NBSP;VIRTUAL&NBSP;VOID&NBSP;FUNC3 () { cout << "Derive::func3" << endl; } virtual void func4 () { cout << "Derive::func4" << endl; }private: int b;}; Void func (base& b) { b.func1 (); b.display (); b.display (10);} Void test1 () { base b1; derive d1; func (B1); func (D1);}
650) this.width=650; "src=" Http://s1.51cto.com/wyfs02/M01/7F/33/wKiom1cWNhzDhp0vAABoHp6VBFc355.png "title=" Capture 5. PNG "alt=" Wkiom1cwnhzdhp0vaabohp6vbfc355.png "/>
Four. The object model of diamond virtual inheritance
Class a{public: virtual void funtest1 () { cout << "A::funtest1 ()" << endl; } virtual void funtest2 () { cout << "A::funtest2 ()" << endl; }private: int _a;}; CLASS&NBSP;B1&NBSP;:VIRTUAL&NBSP;PUBLIC&NBSP;A{PUBLIC:&NBSP;&NBSP;&NBSP;&NBSP;VIRTUAL&NBSP;VOID&NBSP;FUNTEST3 ( ) { cout << "B1:: FunTest3 () " << endl; } virtual void FunTest4 () { cout << "B2 :: FunTest4 () "&NBSP;<<&NBSP;ENDL;&NBSP;&NBSP;&NBSP;&NBSP;}PRivate: int _b1;}; Class b2 :virtual public a{public: virtual void funtest1 ( ) { cout << "B2:: FunTest1 () " << endl; } virtual void FunTest4 () { cout << "B2 :: FunTest4 () " << endl; }private: int _b2;}; class c :p ublic b1, public b2{public: virtual void FunTest1 () { cout << "C: : FunTest1 () " << endl; } virtual void FUNTEST5 () { cout << "C::funtest5 ()" << endl; }private: int _c;}; Void test1 () { c c; c.funtest5 ();}
650) this.width=650; "src=" Http://s3.51cto.com/wyfs02/M02/7F/33/wKiom1cWRMOQOwnuAAFePzlgFeo145.png "title=" Capture 6. PNG "alt=" Wkiom1cwrmoqownuaafepzlgfeo145.png "/>
It can be seen that in virtual inheritance, no matter how many inheritance, the virtual function table of the final subclass is always merged with the virtual function table of the first parent class of the inherited list, but there is a virtual function that overrides the parent class, which naturally overwrites the virtual function with the same name and merges in the virtual table of the parent class.
This article is from the "Liu Lei" blog, make sure to keep this source http://10920610.blog.51cto.com/10910610/1765591
Analysis of C + + polymorphism and its realization mode