Memory layout for C + + objects (bottom) __c++

Source: Internet
Author: User

http://blog.csdn.net/haoel/article/details/3081385

memory layout for C + + objects (bottom)

Chenhao

Http://blog.csdn.net/haoel

<<< Click here to view the previous article Repeat Inheritance

Let's take another look at the case of duplicate inheritance. The so-called duplicate inheritance, that is, a base class is indirectly repeated inherited several times.

The following figure is an inheritance graph, and we overload the F () function of the parent class.


The source code that inherits from its class is shown below. Among them, each class has two variables, one is reshaping (4 bytes), one is the character (1 bytes), but also has its own virtual function, its own overwrite the virtual function of the parent class. As in Subclass D, F () overrides the superclass function, F1 () and F2 () cover the virtual function of its parent class, and Df () is its own virtual function.

Class B

{

Public

int IB;

Char CB;

Public

B (): IB (0), CB (' B ') {}

Virtualvoid f () {cout << "b::f ()" << Endl;}

Virtualvoid Bf () {cout << "B::BF ()" << Endl;}

};

Class B1:public B

{

Public

int IB1;

Char CB1;

Public

B1 (): IB1 (one), CB1 (' 1 ') {}

Virtualvoid f () {cout << "b1::f ()" << Endl;}

Virtualvoid F1 () {cout << "b1::f1 ()" << Endl;}

Virtualvoid Bf1 () {cout << "b1::bf1 ()" << Endl;}

};

Class B2:public B

{

Public

int ib2;

Char CB2;

Public

B2 (): Ib2 (), CB2 (' 2 ') {}

Virtualvoid f () {cout << "b2::f ()" << Endl;}

Virtualvoid F2 () {cout << "b2::f2 ()" << Endl;}

Virtualvoid Bf2 () {cout << "b2::bf2 ()" << Endl;}

};

Class D:public B1, public B2

{

Public

int id;

char cd;

Public

D (): ID (m), CD (' D ') {}

Virtualvoid f () {cout << "d::f ()" << Endl;}

Virtualvoid F1 () {cout << "d::f1 ()" << Endl;}

Virtualvoid F2 () {cout << "d::f2 ()" << Endl;}

Virtualvoid Df () {cout << "D::D F ()" << Endl;}

};

The code we use to access the child-class memory layout is shown below: (under VC + + 2003 and g++ 3.4.4)

Typedefvoid (*fun) (void);

int** pvtab = NULL;

Fun pfun = NULL;

D D;

Pvtab = (int**) &d;

cout << "[0] d::b1::_vptr->" << Endl;

Pfun = (Fun) pvtab[0][0];

cout << "[0]"; Pfun ();

Pfun = (Fun) pvtab[0][1];

cout << "[1]"; Pfun ();

Pfun = (Fun) pvtab[0][2];

cout << "[2]"; Pfun ();

Pfun = (Fun) pvtab[0][3];

cout << "[3]"; Pfun ();

Pfun = (Fun) pvtab[0][4];

cout << "[4]"; Pfun ();

Pfun = (Fun) pvtab[0][5];

cout << "[5] 0x" << pfun << Endl;

cout << "[1] b::ib =" << (int) pvtab[1] << Endl;

cout << "[2] B::CB =" << (char) pvtab[2] << Endl;

cout << "[3] b1::ib1 =" << (int) pvtab[3] << Endl;

cout << "[4] B1::CB1 =" << (char) pvtab[4] << Endl;

cout << "[5] d::b2::_vptr->" << Endl;

Pfun = (Fun) pvtab[5][0];

cout << "[0]"; Pfun ();

Pfun = (Fun) pvtab[5][1];

cout << "[1]"; Pfun ();

Pfun = (Fun) pvtab[5][2];

cout << "[2]"; Pfun ();

Pfun = (Fun) pvtab[5][3];

cout << "[3]"; Pfun ();

Pfun = (Fun) pvtab[5][4];

cout << "[4] 0x" << pfun << Endl;

cout << "[6] B::ib =" << (int) pvtab[6] << Endl;

cout << "[7] B::CB =" << (char) pvtab[7] << Endl;

cout << "[8] b2::ib2 =" << (int) pvtab[8] << Endl;

cout << "[9] b2::cb2 =" << (char) pvtab[9] << Endl;

cout << "[ten] D::id =" << (int) pvtab[10] << Endl;

cout << "[one] d::cd =" << (char) pvtab[11] << Endl;

The results of the program operation are as follows:

GCC 3.4.4

VC + + 2003

[0] d::b1::_vptr->

[0] D::f ()

[1] B::BF ()

[2] d::f1 ()

[3] B1::bf1 ()

[4] D::F2 ()

[5] 0x1

[1] b::ib = 0

[2] b::cb = B

[3] b1::ib1 = One

[4] B1::CB1 = 1

[5] d::b2::_vptr->

[0] D::f ()

[1] B::BF ()

[2] d::f2 ()

[3] B2::BF2 ()

[4] 0x0

[6] b::ib = 0

[7] B::CB = B

[8] b2::ib2 =

[9] b2::cb2 = 2

[A] D::id =

[one] d::cd = D

[0] d::b1::_vptr->

[0] D::f ()

[1] B::BF ()

[2] d::f1 ()

[3] B1::bf1 ()

[4] D::D f ()

[5] 0x00000000

[1] b::ib = 0

[2] b::cb = B

[3] b1::ib1 = One

[4] B1::CB1 = 1

[5] d::b2::_vptr->

[0] D::f ()

[1] B::BF ()

[2] d::f2 ()

[3] B2::BF2 ()

[4] 0x00000000

[6] b::ib = 0

[7] B::CB = B

[8] b2::ib2 =

[9] b2::cb2 = 2

[A] D::id =

[one] d::cd = D

The following is a diagram of a virtual function table in a subclass instance:


We can see that the topmost parent class B has its member variables in B1 and B2 and is inherited by D. And in D, there are instances of B1 and B2, so the members of B have two in the case of D, one in B1 succession and the other in B2 inheritance. So, if we use the following statement, we will produce a ambiguity compilation error:

D D;

D.ib = 0; Ambiguity error

D.b1::ib = 1; That's right

D.b2::ib = 2; That's right


Note that the last two statements in the preceding routine access two variables. Although we eliminated the two semantic compilation errors, the B class had two instances in D, which resulted in duplication of data, which we call inheriting as duplicate inheritance. Duplicate base class data members may not be what we want. Therefore, C + + introduces the concept of virtual base class. multi-Virtual inheritance of diamond type

The emergence of virtual inheritance is to solve the problem of multiple indirect parent classes in duplicate inheritance. The diamond type structure is its most classic structure. And the structure we're going to discuss here:

The above "repeat inheritance" only needs to add the virtual key to the syntax of B1 and B2 inheritance B, and the inheritance diagram below is as follows:


The internal data and interfaces of the classes in the above and previous "repeat inheritance" are exactly the same, but we use virtual inheritance: The omitted source code looks like this:

Class B {...};

Class B1: virtualpublic b{...};

Class B2: virtualpublic b{...};

Class D:public B1, public b2{...};

Before looking at D, let's take a look at the case of a single virtual inheritance . Below is a section of the test program under vc++2003: (because VC + + and GCC memory and the bureau has some details on the difference, so here only give the VC + + program, GCC under the program you can according to the program I gave you to write a to try it):

int** pvtab = NULL;

Fun pfun = NULL;

B1 BB1;

Pvtab = (int**) &bb1;

cout << "[0] b1::_vptr->" << Endl;

Pfun = (Fun) pvtab[0][0];

cout << "[0]";

Pfun (); B1::F1 ();

cout << "[1]";

Pfun = (Fun) pvtab[0][1];

Pfun (); B1::bf1 ();

cout << "[2]";

cout << pvtab[0][2] << Endl;

cout << "[1] = 0x";

cout << (int*) * ((int*) (&BB1) +1) <<endl; B1::ib1

cout << "[2] b1::ib1 =";

cout << (<

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.