C + + class memory distribution (with virtual inheritance) ①---supplement (11) "Effective C + +" __c++

Source: Internet
Author: User
Tags inheritance
reprint: http://www.cnblogs.com/jerry19880126/p/3616999.html

工欲善其事, its prerequisite, let's start with the Visual Studio Tools, step-by-step like the following:

First select the c/c++-> command line on the left, and then write the/d1 reportallclasslayout on the other options, which can see the memory layout of all the related classes, if you write the/D1 Reportsingleclasslayoutxxx (XXX is the class name), only the memory layout for the specified class xxx is played. This configuration is supported for recent VS versions.

The following can be defined as a class, as follows:

1 class Base
2 {
3     int A;
4     int B;
5 Public:
6     void Commonfunction ();
7};

Then you can see that the output box has this arrangement:

You don't want to focus on the memory alignment factor, so member variables are set to int.

From here you can see how normal classes are arranged, and the member variables are sorted in the order in which they are declared (the class is offset to 0), and the member function does not occupy the memory space.

Look at the inheritance and add the following code to the back side:

1 class Derivedclass:public Base
2 {
3     int C;
4 Public:
5     void Derivedcommonfunction ();
6};

Compile, and see the following memory distribution (the memory distribution of the parent class is unchanged, where only the memory distribution of the subclass member variable is discussed):

You can see that the subclass inherits the member variables of the parent class, and on the memory arrangement, first the member variables of the parent class are arranged, then the member variables of the subclass are arranged, and the member functions are not byte-like.

Let's add a virtual function to the base class, temporarily comment out DerivedClass, and look at the memory configuration:

1 class Base
2 {
3     int A;
4     int B;
5 Public:
6     void Commonfunction ();
7     void Virtual virtualfunction ();
8};

This memory structure diagram is divided into two parts, above is the memory distribution, the following is a virtual table, we look at each. vs the compiler takes the virtual table pointer at the beginning of the memory (0 address offset), then there is the member variable; The virtual table is generated below, followed by 0 in the &base1_meta, where the virtual pointer is distributed in memory, and the virtual function is listed below. The 0 on the left is the number of the virtual function, there is only a virtual function, so there is only one, if there are more than one virtual function, there will be a serial number 1, 2 of the virtual function listed.

The compiler creates the virtual table pointer and the virtual table in the constructor.

So how does the compiler use virtual table pointers and virtual tables to achieve polymorphism? It's like this, when you create an object that contains a parent class of a virtual function, the compiler points the virtual table pointer to the virtual function of the parent class when the object is constructed; Similarly, when you create an object for a subclass, the compiler in the constructor will have a virtual table pointer (a subclass with only a virtual table pointer). It comes from the parent class. A virtual table that points to a subclass (the virtual function entry address in this virtual table is a subclass).

So, if you call base *p = new Derived (), the object of the subclass is generated, at construction time, the virtual pointer to the subclass object points to the virtual table of the subclass, and then the conversion from derived* to base* does not change the virtual table pointer, so p-> Virtualfunction, which is actually p->vfptr->virtualfunction, has pointed to the virtualfunction of subclasses at the time of construction, so the virtual function of subclasses is called, which is polymorphism.

Add the subclass below, adding a virtual function to the subclass, as follows:

1 class Derivedclass:public Base
2 {
3     int C;
4 Public:
5     void Derivedcommonfunction ();
6     void Virtual virtualfunction ();
7};

You can see that the child class memory is arranged as follows:

The top half is a memory distribution, and you can see that the virtual table pointer is inherited and still at the beginning of the memory arrangement, the following are the member variables of the parent class A and B, and finally the member variable C of the subclass, note that there is only one virtual table pointer, the subclass does not generate a virtual table pointer, and the bottom half of the virtual table is the same as the parent class.

Let's change the code for the class, like this:

1 class Derivedclass1:public Base
2 {
3     int C;
4 Public:
5     void Derivedcommonfunction ();
6     void Virtual VirtualFunction2 ();
7};

Notice that at this point we do not overwrite the virtual method of the parent class, but instead declare a new subclass virtual method, the memory distribution is as follows:

There is still only one virtual table pointer, but the contents of the virtual table is changed, the virtual table number No. 0 is the virtualfunction of the parent class, and number 1th is the VirtualFunction2 of the subclass. That is, if a DerivedClass object is defined, the virtual table pointer points to the virtual table at construction time, and then if the call is Virtualfunction, then the corresponding virtual function is searched from the parent class, if the call is VirtualFunction2, The corresponding virtual function is then searched from the subclass.

We'll reinvent the class like this:

1 class Derivedclass1:public Base
2 {
3     int C;
4 Public:
5     void Derivedcommonfunction ();
6     void Virtual virtualfunction ();
7     void Virtual VirtualFunction2 ();
8};

As we overwrite both the virtual function of the parent class and the newly added virtual function, we can expect that this is the following memory distribution:

The following is a discussion of multiple inheritance, the following code:

1 class Base
 2 {
 3     int A;
 4     int B;
 5 Public:
 6     void Commonfunction ();
 7     void Virtual virtualfunction ();
 8};
 9 
class Derivedclass1:public Base
{     int c;
Public:     void Derivedcommonfunction ();     void virtual virtualfunction ();
}; 
class Derivedclass2:public Base
{     int D;
Public:     derivedcommonfunction Void ();     void virtual virtualfunction ();
; 
class Derivedderivedclass:public DerivedClass1, public DerivedClass2
{     int e;
Public:     derivedderivedcommonfunction Void ();     void virtual virtualfunction ();
33};

The memory distribution is from the parent class to the subclass, followed by the following:

There is a virtual table pointer in base with an address offset of 0

DerivedClass1 inherits base, the memory arrangement is the later subclass of the late father class.

The DerivedClass2 situation is similar to that of DerivedClass1.

Here we look at this class Derivedderivedclass, which is arranged in parallel with the inherited two parent classes DerivedClass1 and DerivedClass2, and its own member variable E. DERIVEDCLASS1 contains its member variable C, and Base,base has a virtual table pointer with a 0 address offset, followed by member variable A and B;DERIVEDCLASS2 memory configuration similar to DerivedClass1, Notice that there is also a base in the DerivedClass2.

Here are two virtual tables, respectively for DerivedClass1 and DerivedClass2, the number below &deriveddericedclass_meta is the first address offset, The memory offset of the virtual pointer to the virtual table, which is the 16 of the following virtual table, represents the memory offset of {vfptr} in DerivedClass2 in Derivedderivedclass.

If you are using virtual inheritance, like the following:

1 class Derivedclass1:virtual public Base
 2 {
 3     int C;
 4 Public:
 5     void Derivedcommonfunction ();
 6     void Virtual virtualfunction ();
 7};
 8 
 9 class Derivedclass2:virtual public Base
{one     int D;
Public:     void Derivedcommonfunction ();     void virtual virtualfunction ();
}; 
class Derivedderivedclass: Public  DerivedClass1, public DerivedClass2
{     int e;< C26/>20 public:     void Derivedderivedcommonfunction ();     void virtual virtualfunction ();
23};

The base class does not change, but looks down:

DerivedClass1 has changed, the original is the first row of virtual table pointer and base member variable, VFPTR at 0 address offset, but now has two virtual table pointers, one is vbptr, the other is vfptr. Vbptr is the DERIVEDCLASS1 corresponding virtual table pointer that points to the DERIVEDCLASS1 virtual table vbtable, and the other vfptr is the virtual pointer to the virtual base class table, which points to vftable.

Two virtual tables are listed below, the first table is the table that vbptr points to, 8 represents the offset of {vbptr} and {vfptr}, and the second table is the table vfptr points to, and 8 indicates the offset of the virtual pointer of the table in memory.

DERIVEDCLASS2 's memory distribution is similar to DERIVEDCLASS1, there are two virtual pointers, pointing to two virtual tables (the second is the virtual base class table).

Let's take a closer look at the Derivedderivedclass's memory distribution, which has three virtual pointers, but base is only one. The first virtual table contains DerivedClass1, 20 indicates the distance of its virtual pointer {vbptr} from the virtual base table pointer {vfptr}, the second virtual table is contained DerivedClass2, and 12 represents its virtual pointer {vbptr} from the virtual base table pointer {vfptr} Distance, the last table is a virtual base table,-20 indicates the offset of its corresponding virtual pointer {vfptr} in memory.

The effect of virtual inheritance is to reduce duplication of base classes, at the cost of increasing the burden of virtual table pointers (more virtual table pointers).

Ps:
Why does virtual inheritance have a good effect on the diamond-shaped structure inheritance, making sure that only the data from the Diamond Head, the base class, and the virtual function are simply inherited. The answer is on the top, the mechanism of virtual inheritance guarantees that subclasses will have two virtual pointers, one point to their own virtual table, the other to the Virtual base table (which holds the virtual pointers and data of the base class), and because of the multiple inheritance, the virtual base table and the virtual base table pointer have and only one copy, It is therefore entirely guaranteed that the data or virtual functions inherited from the top base class of the diamond structure are and have only one copy.

Here's a summary (when a base class has a virtual function):

1. Each class has virtual pointers and virtual tables;

2. If it is not virtual inheritance, the subclass inherits the virtual pointer of the parent class and points to its own virtual table (which occurs when the object is constructed). How many virtual functions there are, the number of entries in the virtual table. Multiple inheritance, there may be more than one base class virtual table and virtual pointers;

3. If the virtual inheritance, then the subclass will have two virtual pointers, one point to their own virtual table, the other point to the virtual base table, multiple inheritance when the virtual base table and the virtual base table pointers have and only one copy.

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.