C++ diamond inheritance and virtual inheritance

1. What is diamond inheritance?

Single inheritance: When a subclass has only one direct parent class, the inheritance relationship is called single inheritance.
Multiple inheritance: When a subclass has two or more direct parent classes, the inheritance relationship is called multiple inheritance.
Diamond inheritance: Diamond inheritance is C++ multiple inheritance. A manifestation of

A simple diagram can illustrate what diamond inheritance is

Figure one

2. What is the problem with diamond inheritance?

The simplest understanding of inheritance is that the child class copies the members of the parent class. We use the four simplest classes A, B, C, and D with one and only one member variable, m_a = 1, m_b = 2, m_c = 3, m_d = 4. Both B and C inherit Class A, so Class B and Class C each have a copy of m_a that inherits Class A, and Class D inherits both B and C, so that there are two copies of m_a in Class D. Making m_a exist in all four classes leads to data redundancy; and when a class D object accesses a member m_a in the class, there are two copies of m_a, which eventually leads to ambiguity. To sum up, the problem of diamond inheritance is that it will lead to data redundancy and ambiguity.

3. How to solve the problem of diamond inheritance

Solution: Let B virtual inherit A, and C virtual inherit A. A is also called the virtual base class. Virtual inheritance will make the members of the parent class A have only one copy in the final child class D. Note: Do not use virtual inheritance in other places. Basically not used.

Example code:

class A
{
    
    
public:
	int m_a = 1;
};
class B : virtual public A
{
    
    
public:
	int m_b = 2;
};
class C : virtual public A
{
    
    
public:
	int m_c = 3;
};
class D : public B, public C
{
    
    
public:
	int m_d = 4;
};

4. The principle of virtual inheritance to solve the problem of diamond inheritance

We can use the memory window of the compiler to observe the principle of virtual inheritance to solve data redundancy and ambiguity. Still use the simple code above to illustrate the problem.

Insert picture description here
This is a memory window that does not use virtual inheritance. It can be seen that there is data m_a = 1 redundant, and when a class D object accesses m_a, the computer does not know whether it is accessing m_a in B or m_a in C. This causes two Righteousness.

Insert picture description here
This is a memory window that uses virtual inheritance. Here, it can be analyzed that the inherited m_a in the D object is placed at the bottom of the object composition. This m_a belongs to both B and C. The address 0x0020e1b0 in B and the address 0x0020dbbc in C are actually two virtual base table pointers, which point to two virtual base tables respectively, and the offset of m_a is stored in the virtual base table. The computer can find m_a by the offset . This solves the problem of data redundancy and ambiguity inherited by diamonds.

The process of finding m_a using the virtual base table and offset.
Insert picture description here
The virtual base table pointer stored in B, the virtual base table pointed to is stored in the offset as shown in (14) 16 or (20) 10. In the memory window of virtual inheritance, 20 bytes are counted from B. Just visit m_a = 1.
Insert picture description here
The pointer to the virtual base table stored in C, the virtual base table pointed to is stored in the offset as shown in (0c) 16 or (12) 10. In the memory window of virtual inheritance, 12 bytes are counted from C. It also happens to visit m_a = 1.

Guess you like

Origin blog.csdn.net/qq_43579888/article/details/112853884