in this paper, the key reference C + + virtual function Table parsing article (Link: http://blog.csdn.net/haoel/article/details/1948051/ ), Chenhao predecessors This article explain clearly, read after the benefit. There are just a few problems in the code, such as the place where the key virtual function table is concerned, written to
Base b;cout << "virtual function table Address:" << (int*) (&b) << Endl; |
However, in practice (int*) (&b) is not a virtual function table address, but an object b 's address, * (int*) (&b) is the address of the virtual function table. Also, some pointers in the following section have exceptions (or perhaps a different compilation environment?). )。 To do this, I re-coded the experiment and recorded this article.
First, the experimental environment
Native Operating system Linux wm-thinkpad-x240s 3.13.0-44-generic #73-ubuntu SMP Tue Dec 00:22:43utc x86_64 x86_64 x86_64 gnu/linux. Note that the size of the machine means that the pointer length is 8 bytes ; if it is + bit machine, the pointer length is 4 bytes.
We discuss the memory allocation of virtual function based on whether the class containing the virtual function involves inheritance, how to inherit, the single class has no inheritance, general inheritance, multiple inheritance three kinds of cases.
Ii. Single class No inheritance
We write the following code, where class Base contains three virtual functions.
#include <iostream> using namespace std; class Base {public: virtual void f () { cout << "Base::f" << Endl; } virtual void g () { cout << "Base::g" << endl; } virtual void h () { cout < < "Base::h" << endl; }}; typedef void (*fun) (); int main () { Base b; Fun pFun = NULL; cout << "sizeof (b): " << sizeof (b) << endl; cout << address of Object: << ( &B) << endl; cout << "address: of virtual function table" << * (int*) (&b) << endl; pfun = (Fun) (* (int*) (* (int*) (&b))); pfun (); pfun = (Fun) (* (int*) (* (int*) (&b) + 8)); pfun (); pfun = (Fun) (* (int*) (* (int*) ( &B) ( + 16)); pfun (); return 0;} |
Run the result as
650) this.width=650; "src=" http://s3.51cto.com/wyfs02/M00/71/A2/wKiom1XVV3SjC2nlAADKd3l7ftA359.jpg "title=" 1.png " alt= "Wkiom1xvv3sjc2nlaadkd3l7fta359.jpg"/>
according to the running result, the object b the memory size is 8 bytes, which 8 bytes are occupied by storing virtual function table pointers ( - bit machine, pointer 8 bytes).
here, by the way, some C + + The memory allocation knowledge in a class that is not directly related to virtual functions, if there is no virtual function, the memory of the class and the object is the amount of memory of the data member in the class (which needs to be aligned), and the function members in the class do not occupy the amount of storage. So if a class has no data members and virtual functions, How much should the result be? The result should be 0, but an instance of it must occupy a certain amount of space in memory, so the actual result is 1. "Jian refers tooffer" in the similar topic, interested friends can experiment on their own.
Based on the code and its running results, we can infer that its memory allocation is as shown.
650) this.width=650; "src=" http://s3.51cto.com/wyfs02/M02/71/9F/wKioL1XVXJeCUhG7AAHEaKD_Jy4088.jpg "title=" v1.png "alt=" Wkiol1xvxjecuhg7aaheakd_jy4088.jpg "/>
Iii. General Succession
We write the following code, where base is the base class and Derive inherits the base class.
#include <iostream> using namespace std; class Base {public: virtual void f () { cout << "Base::f" << Endl; } virtual void g () { cout << "Base::g" << endl; } virtual void h () { cout < < "Base::h" << endl; }}; class derive : public base {public: void f () { cout << "Derive::f" < <&NBSP;ENDL;&NBSP;}&NBSP;&NBSP;&NBSP;&NBSP;VIRTUAL&NBSP;VOID&NBSP;G1 () { cout << "Derive::g1" << endl; } virtual void h1 () { cout << "Derive::h1" << endl; }}; typedef void (*fun) ( int main);) { Derive d; Fun pFun = NULL; cout << "sizeof (d): " << sizeof (d) << endl; cout << object's address: << (&d) << endl; cout << "Address: of virtual function table" << * (int*) (&d) << endl; pFun = (Fun) (* (int*) (* (int*) (&d)) ); pfun (); pfun = (Fun) (* (int*) (* (int*) (&d) + 8)); pfun (); pfun = (Fun) (* (int*) (* (int*) (&d) + 16); pfun (); pfun = (fun) ( * (int*) (* (int*) (&d) + 24); pfun (); pfun = (FuN) (* (int*) (* (int*) (&d) + 32); pfun (); return 0;} |
Run the result as
650) this.width=650; "src=" http://s3.51cto.com/wyfs02/M00/71/A2/wKiom1XVWvyAbppoAADoBPPPuzQ059.jpg "title=" 2.png " alt= "Wkiom1xvwvyabppoaadobpppuzq059.jpg"/>
Based on the code and its running results, we can infer that its memory allocation is as shown.
650) this.width=650; "src=" http://s3.51cto.com/wyfs02/M01/71/9F/wKioL1XVXSDSpDtpAAG4RRuf_BQ431.jpg "title=" v2.png "alt=" Wkiol1xvxsdspdtpaag4rruf_bq431.jpg "/>
Iv. Multiple Inheritance
We write the following code, class derive inheriting class base1 , base2 , base3
#include <iostream> using namespace std; class Base1 {public: virtual void f () { cout << "Base1::f" << endl; } virtual void g () { cout << " Base1::g " << endl; } virtual void h () { cout << "Base1::h" << endl; }}; class Base2 {public: virtual void f () { cout << "Base2::f" << endl; } virtual void g () { cout << " Base2::g " << endl; } virtual void h () { cout << "Base2::h" << endl; }}; class Base3 {public: virtual void f() { cout << "Base3::f" << endl; } Virtual void g () { cout << "Base3::g" &NBSP;<<&NBSP;ENDL;&NBSP;} virtual void h () { cout << "Base3::h" < < endl; }}; class Derive : public Base1, public Base2, Public base3 {public: void f () { cout << " Derive::f " << endl; } virtual void g1 () { cout << "DERIVE::G1" << endl; } virtual void &NBSP;H1 () { cout << "DERIVE::H1" << endl; }}; typedef void (*fun) (void); int main () { Derive d; fun pfun = null; int** pvtab = (int**) &d; cout < < "sizeof (b): " << sizeof (d) << endl; pFun = (Fun) pvtab[0][0]; pfun (); pfun = (Fun) Pvtab[0][2]; pfun (); pfun = ( Fun) Pvtab[0][4]; pfun (); pfun = (fun) pVtab[0][6] ; pfun (); pfun = (fun) pVtab[0][8]; pfun (); pfun = (fun) pvtab[1][0]; Pfun (); pfun = (fun) pvtab[1][2]; pfun (); pFun = (Fun) pvtab[1][4]; pfun (); pFun = (Fun) Pvtab[2][0]; pfun (); pfun = (fun) pVtab[2][2]; pfun (); pfun = (fun) pVtab[2][4]; pfun (); return 0;} |
Run results
650) this.width=650; "src=" http://s3.51cto.com/wyfs02/M01/71/A2/wKiom1XVW17icx1QAADnJINvDxs178.jpg "title=" 3.png " alt= "Wkiom1xvw17icx1qaadnjinvdxs178.jpg"/>
Based on the code and its running results, we can infer that its memory allocation is as shown.
650) this.width=650; "src=" http://s3.51cto.com/wyfs02/M00/71/9F/wKioL1XVXfDDdf3VAALywYTDdCA501.jpg "title=" v3.png "alt=" Wkiol1xvxfdddf3vaalywytddca501.jpg "/>
This article from "Talking Cabbage" blog, declined reprint!
C + + virtual function memory allocation