Deep Exploration of C + + object models

Source: Internet
Author: User

The so-called enemy, win. Only with a deep understanding of the memory layout of C + + objects can we use the C + + language more skillfully.
a combination of a single inheritance and multiple inheritance in the running environment vs2013

Class C
{public
:
    C (): C (1) {}
private:
    int C;
};
Class B1:p ublic c
{public
:
    B1 (): C (), B1 (2) {}
private:
    int b1;
};
Class B2:p ublic c
{public
:
    B2 (): C (), B2 (3) {}
private:
    int b2;
};
Class A:p ublic B1, public B2
{public
:
    A (): B1 (), B2 (), a (4) {}
private:
    int A;
};
int main ()
{
    A F1;
    Cout<<sizeof (F1);
    return 0;
}

Because it is not virtual inheritance, the inheritance relationship is as follows:


Let's go to memory to see how the object space is distributed:

0x00caf800 ...  . Member data for//B1 in C
0x00caf804 ...  .//B1-specific membership data
, and so on. 0x00caf808 ....  //B2 's member Data
0x00caf80c ...  .//B2-specific member Data
(c) 0x00caf810 ...  .//a-specific member data
0x00caf814  cc  cc cc CC????

So the final data distribution is this:

So according to the object model, you should know how much the output value is. two. Diamond Inheritance

Class C
{public
:
    C (): C (1) {}
private:
    int C;
};
Class B1:virtual public C
{public
:
    B1 (): C (), B1 (2) {}
private:
    int B1;
Class B2:virtual public C
{public
:
    B2 (): C (), B2 (3) {}
private:
    int B2;
Class A:p ublic B1, public B2
{public
:
    A (): B1 (), B2 (), a (4) {}
private:
    int A;
};
int main ()
{
    A aa;
    B1 BB1;
    B2 Bb2;
    C cc;
    cout << sizeof (AA);//24
    cout << sizeof (BB1);//12 cout
    << sizeof (BB2);//12
    cout < < sizeof (cc);//4 return
    0;
}

As its name, the inheritance relationship is as follows:

First, let's go to memory to see how the object space is distributed.
Gets the address of the object of Class A:

0X0114FC84  DD  /????
0x0114fc88  //b1 Special Data
0x0114fc8c  AC db  //????
0X0114FC90  //b2 Special Data
0x0114fc94
0x0114fc98  01, which is unique in the//a  of//c specific data

Based on this memory address alone, it is clear that we do not know what the data of a similar address in 0x0114fc84,0x0114fc8c does. So we'll go to the address and find out:

0x0083dd70 ...  .
0x0083dd74 ...  //20.
0x0083dbac ...  .
0x0083dbb0  0c ...  //12

Contact above, we can learn that the change of address point to the content is B1 and B2 class to Class A data offset.
Finally we can get the data distribution:
three. Virtual inheritance with imaginary functions

Class B1
{public
:
    B1 (): B1 (1) {}
    virtual void fun1 () {}
    virtual void fun2 () {}
private:
    int b1;
};

Class B2
{public
:
    B2 (): B2 (2) {}
    virtual void Fun3 () {}
    virtual void Fun4 () {}
private:
    int b2;
};

Class A:p ublic B1, public B2
{public
:
    A (): B1 (), B2 (), a (3) {}
    void Fun1 () {};
    void Fun2 () {};
    void Fun3 () {};
    virtual void Fun5 () {};
Private:
    int A;
};

int main ()
{
    A F1;
    Cout<<sizeof (F1);//20 return
    0;
}

For a virtual table, see my previous blog.
As the code indicates, the inheritance relationship is as follows:

Here you can guess what the object space is

Go to Memory:

0X00FBFDDC  cc 0f  ??.. Virtual table address
0x00fbfde0 ...  //class B1 member variable B1
0x00fbfde4  a4 cc 0f  ??.. Virtual table address
0x00fbfde8 ...  ///class B2 member variable B2
0x00fbfdec  ...//member variable A of Class A

So what are the functions in the virtual table that the first virtual table pointer points to, and what are the functions in the second virtual table?
Let's go to the virtual table together:
First virtual table

0X000FCC90  0f  //a::fun1 ()
0x000fcc94  de 0f  ?...//a::fun2 ()
0x000fcc98  0f  e...//a::fun5 ()
0x000fcc9c ...  ..

By running these three functions, we can know that a::fun1 (), a::fun2 (), A::fun5 ()

Second virtual table

0X000FCCA4  ff 0f ...  //a::fun3 ()
0x000fcca8  ca 0f  ?...//b2::fun4 ()
0X000FCCAC ...  .

By running these three functions, we can know that a::fun13 (), B::fun4 ()

so we can draw a conclusion: In this class inheritance, the object space maintains two virtual tables, and the new virtual functions in the derived class are placed in the first virtual table.
Finally we can get the data distribution:
four. Diamond inheritance with virtual functions

Class C
{public
:
    virtual void Fun () {}
private:
    int c;
};
Class B1:virtual public C
{public
:
    virtual void Fun () {}
    virtual void fun1 () {}
private:
    int b1;
};
Class B2:virtual public C
{public
:
    virtual void Fun () {}
    virtual void fun2 () {}
private:
    int b2;
};
Class A:p ublic B1, public B2
{public
:
    void Fun () {}
private:
    int A;
};
typedef void (*fun) ();
void Funtest (A&b)
{
    int i = 0;
    Int*p = (int*) * ((int*) (&b) +3);
    while (*p)
    {
        fun fn = (fun) *p;
        fn ();
        p++
    }
}
int main ()
{
    C F1;
    B1 F2;
    B2 f3;
    A F4;
    cout << sizeof (F1)//8
    cout << sizeof (F2);//20 cout
    << sizeof (F3);//20
    cout << sizeof (F4);//36 return
    0;
}

The inheritance relationship is as follows

Since the structure of C object is more complicated, we start with the B1 analysis

1.B1
First notice there is no constructor here, and if there is a constructor, the structure will change.
Assigning c,b1 to 1,2 through the Watch window
Open Memory:

0x005ffca8  7c cc 1e  |?.. //????
0X005FFCAC  cc 1e  ??.. //????
0x005ffcb0 ...  //class B1 data B1
0x005ffcb4  cc 1e  ??.. //????
0x005ffcb8 ...  //Class C data C

We don't know what these three addresses in memory represent, just go to that address to see
(1) 0x005ffca8 7c CC 1e 01

0x011ecc7c  1e  d ...
0x011ecc80 ...  .

Obviously this is a virtual table, which is the new function in B1 fun1 ()
(2) 0X005FFCAC cc 1e 01

0X011ECC90  FC FF FF FF  ?...
0x011ecc94 ...  .

This is an offset that represents the offset to the base class data
(3) 0x005ffcb4 cc 1e 01

0x011ecc88  1e  (...
0x011ecc8c ...  .

is a virtual table, which is an overridden fun () in B1.

This allows for B1 of object data distribution:

Note: If there is no new function in the B1, then the B1 object maintains only a virtual table;
If there is a new function in the B1, then the B1 object maintains two virtual tables

2.A

0x002efde4  2e  ?.. Class B1 Virtual table pointer
0x002efde8  DD 2e  (?.. Offsets to base class data
0x002efdec ...  //class B1-specific data

0x002efdf0  2e  ?.. Class B2 Virtual table pointer
0x002efdf4  DD 2e  4?.. Offset to base class data
0x002efdf8 ...  //class B2-specific data

0X002EFDFC  ...//class B2-specific data

0x002efe00  dd 2e   ?.. Class C Virtual table pointer
0x002efe04 ...  //Class C-specific data

(1) 0x002efde4-DD 2e 01

0x012edd08  2e I. ...
0x012edd0c ...  .

By running this function on this virtual table, we know that the function is b1::fun1 ()
(2) 0x002efdf0 DD 2e 01

0X012EDD14  2e  2 ...
0x012edd18  00 00 00 00  

By running this function on this virtual table, we know that the function is b2::fun2 ()
(3) 0x002efe00 DD 2e 01

0X012EDD20  2e  D ...
0x012edd24 ...  .

By running this function on this virtual table, we know that the function is A::fun ()

Finally, we can get the object data distribution of Class A

At this point a object maintained three virtual tables, but we are not very clear about the specific role of these three virtual tables, we can add a virtual function in the class to test:
Class C To add the function virtual void fun3 ();
Class B1 join function virtual void fun4 ();
Class B2 join function virtual void fun5 ();
Class A joins the function virtual void fun6 ();
The inheritance relationship at this point is as shown

Call the functions in each virtual table, and get the object model to

So: A's object maintains three virtual tables altogether.
The first is the B1 virtual table, which contains the new virtual function in class B1, and the new virtual function in Class A.
The second is the virtual table of B2, which contains the new virtual function in class B2.
The third is the virtual table of C, which contains the virtual table of Class C, and if the derived class of Class C overrides the function on the virtual table, the function address becomes the rewritten address

Related Article

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.