How can I avoid the diamond of death by using multiple inheritance?

http://en.wikipedia.org/wiki/Diamond_problem

I know what this means, but what steps can I take to avoid this?

+45
c ++ multiple-inheritance
Sep 26 '08 at 1:36
source share
9 answers

Practical example:

class A {}; class B : public A {}; class C : public A {}; class D : public B, public C {}; 

Notice how class D inherits from both B and C. But both B and C inherit from A. This will result in 2 copies of class A being included in the vtable.

To solve this problem, we need virtual inheritance. This is class A, which should actually be inherited. Thus, this will fix the problem:

 class A {}; class B : virtual public A {}; class C : virtual public A {}; class D : public B, public C {}; 
+54
Sep 26 '08 at 12:57
source share

virtual inheritance. This is what it is.

+14
Sep 26 '08 at 1:39
source share

I would only stick to multiple interface inheritance. Although multiple class inheritance is sometimes attractive, it can also be confusing and painful if you rely on it regularly.

+12
Sep 26 '08 at 1:49
source share

Inheritance is a strong, powerful weapon. Use it only when you really need it. Earlier, the inheritance of diamonds was a sign that I was going to go far according to classification, stating that the user is an “employee”, but they are also a “widget listener”, but also ...

In these cases, it is easy to hit several inheritance issues.

I solved them using composition and pointers back to the owner:

Before:

 class Employee : public WidgetListener, public LectureAttendee { public: Employee(int x, int y) WidgetListener(x), LectureAttendee(y) {} }; 

After:

 class Employee { public: Employee(int x, int y) : listener(this, x), attendee(this, y) {} WidgetListener listener; LectureAttendee attendee; }; 

Yes, access rights are different, but if you can avoid this approach without duplicating the code, this is better because it is less powerful. (You can save food if you have no alternative.)

+5
Sep 27 '08 at 6:09
source share

This link will answer your question in detail:

https://isocpp.org/wiki/faq/multiple-inheritance

+3
Oct 25 2018-10-25
source share
 class A {}; class B : public A {}; class C : public A {}; class D : public B, public C {}; 

In this, the attributes of class A are repeated twice in class D, which increases memory usage ... Therefore, to save memory, we create a virtual attribute for all inherited attributes of class A that are stored in Vtable.

+3
Jul 15 2018-12-15T00:
source share

Well, the great thing about Scary Britain is that it is a mistake when this happens. The best way to avoid is to figure out the inheritance structure in advance. For example, in one project in which I work, there are viewers and editors. Editors are logical subclasses of Viewers, but since all viewers are subclasses - TextViewer, ImageViewer, etc., the Editor does not output from the Viewer, which allows the final TextEditor, ImageEditor classes to avoid diamond.

In cases where a diamond cannot be avoided using virtual inheritance. However, the biggest caveat with virtual databases is that the virtual database constructor must be called by the most derived class, which means that the class that gets it has virtually no control over the constructor parameters. In addition, having a virtual database tends to be penalized for performance / space when casting through a chain, although I do not believe that there is a large portion of the penalty for more than the first.

In addition, you can always use a diamond if you clearly indicate which base you want to use. Sometimes this is the only way.

+1
Sep 26 '08 at 2:01
source share

I would suggest a better class design. I'm sure there are some problems that are best solved with multiple inheritance, but check if there is another way.

If not, use virtual functions / interfaces.

0
Sep 26 '08 at 12:50
source share

Use inheritance by delegation. Then both classes will point to base A, but must implement methods that redirect to A. It has the side effect of turning the protected members of A into "private" members in B, C and D, but now you don’t need a virtual one and you don’t have a diamond.

0
Feb 11 '11 at 23:24
source share



All Articles