Implementation Mechanism of C ++ virtual base class

Source: Internet
Author: User

In "Deep Exploration C ++ object model", there is a question that is frequently asked by the technical staff when they go to a company interview: In C ++, OBJ is a class object, and P is a pointer to OBJ. This class contains a data member mem. May I ask OBJ. MEM and p-> mem differ in implementation and efficiency.

The answer is: there is a major difference only in one case, and the following three conditions must be met:

(1). obj is the object of a virtual inherited derived class.
(2) mem is a member derived from the virtual base class.
(3) P is a pointer of the base class type.

In this case, P-> MEM has two more intermediate layers than obj. mem. (In this case, P-> mem is obviously slower than obj. mem)

Why?

If you are curious, read it.

1. The use of virtual base classes and the differences between virtual functions implemented for polymorphism are aimed at solving the ambiguity of Multi-inheritance.

Example:

Class
{
Public:
Int;
};

Class B: virtual public
{
Public:
Int B;
};

Class C: virtual public
{
Public:
Int C;
};

Class D: Public B, public C
{
Public:
Int D;
};

In the above diamond inheritance system, if there is no virtual inheritance, there will be two members of 'A' in 'd; inherited, there will be a lot of ambiguity in use. With the addition of virtual inheritance, in D, there is only one copy of the int A; member of A. The copy is not from B, nor from C, but a separate copy, how is the compiler implemented ??

Before answering this question, first think about what is sizeof (A), sizeof (B), sizeof (C), sizeof (d? (Under linux2.6 of 32-bit x86, or under vc2005)

Under linux2.6, the result is as follows: sizeof (A) = 4; sizeof (B) = 12; sizeof (c) = 12; sizeof (d) = 24

Why is sizeof (B) 12? Why is there an Extra pointer (which is the same as the implementation of the virtual function)? What is the pointer?

So why is sizeof (d) 24? That's because in addition to inheriting B in B, C in C, A in A, and D's own member D, B also inherits, two pointers (one for B and one for C) Come out of C ). Once again, int A in D is not from B or C, but another member directly pulled from.

If the object D: d is declared;
The memory layout of D is as follows:

Vb_ptr: pointer inherited from B
Int B: inherited from B Public Member
Vc_ptr: pointer inherited from C
Int C: common member inherited from C
Int D: D Public Member
Int A: A Public Member inherited from.

So what will happen in the following usage?

D dd;
B * pb = & DD;
Pb->;

As mentioned above, int A in DD does not inherit from B or C, so how does Pb-> A in B know that it points to the sixth item in DD memory?

That is the clever use of the pointer vb_ptr. The principle is as follows: (In fact, the implementation of G ++ 3.4.3 is more complicated. I don't know why, but here I only talk about the principle, so I simplified the process and content)

First, vb_ptr points to the address of an integer, where the integer is the offset from the beginning of the int A (here, vb_ptr points to the address where it is placed 20, in bytes ). The compiler does this:

First, find vb_ptr (this is not needed, because in G ++, vb_ptr is the first item in B *, huh, huh ), then obtain the content of the address pointed to by vb_ptr (20 in this example), and add the content to the pointer PB to get the address of Pb->.

Therefore, in this case, the base class members can be found only after two intermediate layers are converted with pointers, and the base class members can be found during running.

It can also be inferred that the content of vb_ptr and vc_ptr in DD are the same, and they all point to the same address, so that the address is put 20 (in this example)

The following statement:

A * pA = & DD;
Pa-> A = 4;

This statement does not need to be converted, because during compilation, the compiler knows where the member A is inserted in the DD (in this example, it is the end ), therefore, the running efficiency and DD in this statement are as follows. A is the same (at least similar)

This is the basic principle of virtual base class implementation.

Note: The position of the pointer and the memory layout of the base class members in the derived class members are uncertain. That is to say, the standard does not stipulate that int A must be placed at the end, it's just the implementation of the G ++ compiler. The C ++ standard only defines the principles of this mechanism. For specific implementation, such as the emission sequence and optimization of each member, it is determined by each compiler vendor ~

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.