How can I avoid the Diamond of Death when using multiple inheritance?











up vote
49
down vote

favorite
14












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



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










share|improve this question
























  • I want to say "don't use multiple inheritance," but that's just being a cad. I'd love to see a good answer to this, too.
    – Chris Charabaruk
    Sep 26 '08 at 1:43






  • 2




    "Diamond of Death" is a bit dramatic. What exactly do you want to know.
    – Martin York
    Sep 26 '08 at 3:57






  • 6




    It's widely known as the Deadly Diamond of Death. Google it.
    – ilitirit
    Sep 26 '08 at 10:56






  • 11




    Google tells me it'susually known as the "Diamond Problem", except in the Java community, where the more drastic term is used to justify why Java "solves" the problem by disallowing it.
    – wolfgang
    Dec 15 '11 at 9:55






  • 1




    There is no "death" here. Both virtual and "standard" inheritance have their use (very rarely, though).
    – Alexandre C.
    Mar 8 '12 at 20:24

















up vote
49
down vote

favorite
14












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



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










share|improve this question
























  • I want to say "don't use multiple inheritance," but that's just being a cad. I'd love to see a good answer to this, too.
    – Chris Charabaruk
    Sep 26 '08 at 1:43






  • 2




    "Diamond of Death" is a bit dramatic. What exactly do you want to know.
    – Martin York
    Sep 26 '08 at 3:57






  • 6




    It's widely known as the Deadly Diamond of Death. Google it.
    – ilitirit
    Sep 26 '08 at 10:56






  • 11




    Google tells me it'susually known as the "Diamond Problem", except in the Java community, where the more drastic term is used to justify why Java "solves" the problem by disallowing it.
    – wolfgang
    Dec 15 '11 at 9:55






  • 1




    There is no "death" here. Both virtual and "standard" inheritance have their use (very rarely, though).
    – Alexandre C.
    Mar 8 '12 at 20:24















up vote
49
down vote

favorite
14









up vote
49
down vote

favorite
14






14





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



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










share|improve this question















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



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







c++ multiple-inheritance






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 15 '15 at 5:23









Mateen Ulhaq

11.2k114690




11.2k114690










asked Sep 26 '08 at 1:36









ilitirit

8,192156597




8,192156597












  • I want to say "don't use multiple inheritance," but that's just being a cad. I'd love to see a good answer to this, too.
    – Chris Charabaruk
    Sep 26 '08 at 1:43






  • 2




    "Diamond of Death" is a bit dramatic. What exactly do you want to know.
    – Martin York
    Sep 26 '08 at 3:57






  • 6




    It's widely known as the Deadly Diamond of Death. Google it.
    – ilitirit
    Sep 26 '08 at 10:56






  • 11




    Google tells me it'susually known as the "Diamond Problem", except in the Java community, where the more drastic term is used to justify why Java "solves" the problem by disallowing it.
    – wolfgang
    Dec 15 '11 at 9:55






  • 1




    There is no "death" here. Both virtual and "standard" inheritance have their use (very rarely, though).
    – Alexandre C.
    Mar 8 '12 at 20:24




















  • I want to say "don't use multiple inheritance," but that's just being a cad. I'd love to see a good answer to this, too.
    – Chris Charabaruk
    Sep 26 '08 at 1:43






  • 2




    "Diamond of Death" is a bit dramatic. What exactly do you want to know.
    – Martin York
    Sep 26 '08 at 3:57






  • 6




    It's widely known as the Deadly Diamond of Death. Google it.
    – ilitirit
    Sep 26 '08 at 10:56






  • 11




    Google tells me it'susually known as the "Diamond Problem", except in the Java community, where the more drastic term is used to justify why Java "solves" the problem by disallowing it.
    – wolfgang
    Dec 15 '11 at 9:55






  • 1




    There is no "death" here. Both virtual and "standard" inheritance have their use (very rarely, though).
    – Alexandre C.
    Mar 8 '12 at 20:24


















I want to say "don't use multiple inheritance," but that's just being a cad. I'd love to see a good answer to this, too.
– Chris Charabaruk
Sep 26 '08 at 1:43




I want to say "don't use multiple inheritance," but that's just being a cad. I'd love to see a good answer to this, too.
– Chris Charabaruk
Sep 26 '08 at 1:43




2




2




"Diamond of Death" is a bit dramatic. What exactly do you want to know.
– Martin York
Sep 26 '08 at 3:57




"Diamond of Death" is a bit dramatic. What exactly do you want to know.
– Martin York
Sep 26 '08 at 3:57




6




6




It's widely known as the Deadly Diamond of Death. Google it.
– ilitirit
Sep 26 '08 at 10:56




It's widely known as the Deadly Diamond of Death. Google it.
– ilitirit
Sep 26 '08 at 10:56




11




11




Google tells me it'susually known as the "Diamond Problem", except in the Java community, where the more drastic term is used to justify why Java "solves" the problem by disallowing it.
– wolfgang
Dec 15 '11 at 9:55




Google tells me it'susually known as the "Diamond Problem", except in the Java community, where the more drastic term is used to justify why Java "solves" the problem by disallowing it.
– wolfgang
Dec 15 '11 at 9:55




1




1




There is no "death" here. Both virtual and "standard" inheritance have their use (very rarely, though).
– Alexandre C.
Mar 8 '12 at 20:24






There is no "death" here. Both virtual and "standard" inheritance have their use (very rarely, though).
– Alexandre C.
Mar 8 '12 at 20:24














8 Answers
8






active

oldest

votes

















up vote
59
down vote



accepted










A 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 & C. But both B & C inherit from A. That will result in 2 copies of the class A being included in the vtable.



To solve this, we need virtual inheritance. It's class A that needs to be virtually inherited. So, this will fix the issue:



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





share|improve this answer

















  • 3




    That's only avoiding A being twice in memory, it does not avoid any problems caused by the Diamond. See tinyurl.com/abtjcb ; how do you implement getDepartment, that it always returns the right thing? You can't! Your design is flawed. See tinyurl.com/ccjnk6
    – Mecki
    Feb 25 '09 at 16:31






  • 5




    That's what scope is for. Alternatively you can use the "using" statement in class D.
    – Mark Ingram
    Feb 26 '09 at 9:12






  • 2




    Isn't this answer only valid for classes you have control over? If B and C are in a library provided by someone else, or they're part of a code base you cannot change this 'solution' doesn't work at all. It also goes against the whole principle of OOP that a base class shouldn't be concerned with the derived classes, but here B and C suddenly have to change because of some class D that was added later in the day.
    – jbx
    Oct 18 '15 at 20:12


















up vote
14
down vote













virtual inheritance. That's what it's there for.






share|improve this answer

















  • 1




    Where in the inheritance hierarchy?
    – ilitirit
    Sep 26 '08 at 1:47










  • If you have B and C derived from A, and D derived from B and C, then B and C must both declare A as a virtual base. Specifically, each instance of virtual inheritance of the same class is collapsed into one class. Any non-virtual ones will not be collapsed, causing the diamond to recur.
    – coppro
    Sep 26 '08 at 2:03










  • imho, that's a solution to the problem, but not a way to avoid it...
    – Chris M.
    Sep 26 '08 at 13:02










  • While virtual inheritence is the feature for getting around the Diamond of Death problem, I think that there are better ways to work around the problem. Namely, inheriting from abstract base classes (interface classes) instead of inheriting from multiple concrete classes.
    – Nick Haddad
    Sep 26 '08 at 13:03






  • 4




    Not a complete answer.
    – Lee Louviere
    Feb 11 '11 at 23:26


















up vote
12
down vote













I'd stick to using multiple inheritance of interfaces only. While multiple inheritance of classes is attractive sometimes, it can also be confusing and painful if you rely on it regularly.






share|improve this answer























  • C++ doesn't have interfaces.
    – Arafangion
    Apr 12 '12 at 7:40






  • 8




    @Arafangion C++ does have interfaces, although it is not a language construct as for example found in Java. Instead, they are just pure virtual base classes.
    – jlh
    Jun 11 '12 at 12:01










  • @jlh: I'll conceed that point, although I'd contend that while C++ itself doesn't have interfaces, the language does allow you to implement them.
    – Arafangion
    Jun 11 '12 at 23:58






  • 3




    I never met somebody who did not understand that it would mean inheriting pure abstract classes in this context
    – BlueTrin
    Nov 8 '14 at 9:00


















up vote
5
down vote













Inheritance is a strong, strong weapon. Use it only when you really need it. In the past, diamond inheritance was a sign that I was going to far with classification, saying that a user is an "employee" but they are also a "widget listener", but also a ...



In these cases, it's easy to hit multiple inheritance issues.



I solved them by 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 get away with such an approach, without duplicating code, it's better because it's less powerful. (You can save the power for when you have no alternative.)






share|improve this answer

















  • 1




    And what you did is that you multiplied your memory usage by a lot. No thanks.
    – spectre
    Nov 3 '15 at 19:49










  • Composition vs Inheritance. Fight!
    – Alexander Shishenko
    Feb 3 '16 at 10:45


















up vote
3
down vote













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


In this the attributes of Class A repeated twice in Class D which makes more memory usage... So to save memory we make a virtual attribute for all inherited attributes of class A which are stored in a Vtable.






share|improve this answer






























    up vote
    1
    down vote













    Well, the great thing about the Dreaded Diamond is that it's an error when it occurs. The best way to avoid is to figure out your inheritance structure beforehand. For instance, one project I work on has Viewers and Editors. Editors are logical subclasses of Viewers, but since all Viewers are subclasses - TextViewer, ImageViewer, etc., Editor does not derive from Viewer, thus allowing the final TextEditor, ImageEditor classes to avoid the diamond.



    In cases where the diamond is not avoidable, using virtual inheritance. The biggest caveat, however, with virtual bases, is that the constructor for the virtual base must be called by the most derived class, meaning that a class that derives virtually has no control over the constructor parameters. Also, the presence of a virtual base tends to incur a performance/space penalty on casting through the chain, though I don't believe there is much of a penalty for more beyond the first.



    Plus, you can always use the diamond if you are explicit about which base you want to use. Sometimes it's the only way.






    share|improve this answer




























      up vote
      0
      down vote













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



      If not, use virtual functions/interfaces.






      share|improve this answer

















      • 1




        "check to see if there is another way first" Why?
        – curiousguy
        Nov 1 '11 at 3:17


















      up vote
      0
      down vote













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






      share|improve this answer





















        Your Answer






        StackExchange.ifUsing("editor", function () {
        StackExchange.using("externalEditor", function () {
        StackExchange.using("snippets", function () {
        StackExchange.snippets.init();
        });
        });
        }, "code-snippets");

        StackExchange.ready(function() {
        var channelOptions = {
        tags: "".split(" "),
        id: "1"
        };
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function() {
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled) {
        StackExchange.using("snippets", function() {
        createEditor();
        });
        }
        else {
        createEditor();
        }
        });

        function createEditor() {
        StackExchange.prepareEditor({
        heartbeatType: 'answer',
        convertImagesToLinks: true,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: 10,
        bindNavPrevention: true,
        postfix: "",
        imageUploader: {
        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
        allowUrls: true
        },
        onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        });


        }
        });














         

        draft saved


        draft discarded


















        StackExchange.ready(
        function () {
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f137282%2fhow-can-i-avoid-the-diamond-of-death-when-using-multiple-inheritance%23new-answer', 'question_page');
        }
        );

        Post as a guest















        Required, but never shown

























        8 Answers
        8






        active

        oldest

        votes








        8 Answers
        8






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes








        up vote
        59
        down vote



        accepted










        A 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 & C. But both B & C inherit from A. That will result in 2 copies of the class A being included in the vtable.



        To solve this, we need virtual inheritance. It's class A that needs to be virtually inherited. So, this will fix the issue:



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





        share|improve this answer

















        • 3




          That's only avoiding A being twice in memory, it does not avoid any problems caused by the Diamond. See tinyurl.com/abtjcb ; how do you implement getDepartment, that it always returns the right thing? You can't! Your design is flawed. See tinyurl.com/ccjnk6
          – Mecki
          Feb 25 '09 at 16:31






        • 5




          That's what scope is for. Alternatively you can use the "using" statement in class D.
          – Mark Ingram
          Feb 26 '09 at 9:12






        • 2




          Isn't this answer only valid for classes you have control over? If B and C are in a library provided by someone else, or they're part of a code base you cannot change this 'solution' doesn't work at all. It also goes against the whole principle of OOP that a base class shouldn't be concerned with the derived classes, but here B and C suddenly have to change because of some class D that was added later in the day.
          – jbx
          Oct 18 '15 at 20:12















        up vote
        59
        down vote



        accepted










        A 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 & C. But both B & C inherit from A. That will result in 2 copies of the class A being included in the vtable.



        To solve this, we need virtual inheritance. It's class A that needs to be virtually inherited. So, this will fix the issue:



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





        share|improve this answer

















        • 3




          That's only avoiding A being twice in memory, it does not avoid any problems caused by the Diamond. See tinyurl.com/abtjcb ; how do you implement getDepartment, that it always returns the right thing? You can't! Your design is flawed. See tinyurl.com/ccjnk6
          – Mecki
          Feb 25 '09 at 16:31






        • 5




          That's what scope is for. Alternatively you can use the "using" statement in class D.
          – Mark Ingram
          Feb 26 '09 at 9:12






        • 2




          Isn't this answer only valid for classes you have control over? If B and C are in a library provided by someone else, or they're part of a code base you cannot change this 'solution' doesn't work at all. It also goes against the whole principle of OOP that a base class shouldn't be concerned with the derived classes, but here B and C suddenly have to change because of some class D that was added later in the day.
          – jbx
          Oct 18 '15 at 20:12













        up vote
        59
        down vote



        accepted







        up vote
        59
        down vote



        accepted






        A 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 & C. But both B & C inherit from A. That will result in 2 copies of the class A being included in the vtable.



        To solve this, we need virtual inheritance. It's class A that needs to be virtually inherited. So, this will fix the issue:



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





        share|improve this answer












        A 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 & C. But both B & C inherit from A. That will result in 2 copies of the class A being included in the vtable.



        To solve this, we need virtual inheritance. It's class A that needs to be virtually inherited. So, this will fix the issue:



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






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Sep 26 '08 at 12:57









        Mark Ingram

        42.4k44148211




        42.4k44148211








        • 3




          That's only avoiding A being twice in memory, it does not avoid any problems caused by the Diamond. See tinyurl.com/abtjcb ; how do you implement getDepartment, that it always returns the right thing? You can't! Your design is flawed. See tinyurl.com/ccjnk6
          – Mecki
          Feb 25 '09 at 16:31






        • 5




          That's what scope is for. Alternatively you can use the "using" statement in class D.
          – Mark Ingram
          Feb 26 '09 at 9:12






        • 2




          Isn't this answer only valid for classes you have control over? If B and C are in a library provided by someone else, or they're part of a code base you cannot change this 'solution' doesn't work at all. It also goes against the whole principle of OOP that a base class shouldn't be concerned with the derived classes, but here B and C suddenly have to change because of some class D that was added later in the day.
          – jbx
          Oct 18 '15 at 20:12














        • 3




          That's only avoiding A being twice in memory, it does not avoid any problems caused by the Diamond. See tinyurl.com/abtjcb ; how do you implement getDepartment, that it always returns the right thing? You can't! Your design is flawed. See tinyurl.com/ccjnk6
          – Mecki
          Feb 25 '09 at 16:31






        • 5




          That's what scope is for. Alternatively you can use the "using" statement in class D.
          – Mark Ingram
          Feb 26 '09 at 9:12






        • 2




          Isn't this answer only valid for classes you have control over? If B and C are in a library provided by someone else, or they're part of a code base you cannot change this 'solution' doesn't work at all. It also goes against the whole principle of OOP that a base class shouldn't be concerned with the derived classes, but here B and C suddenly have to change because of some class D that was added later in the day.
          – jbx
          Oct 18 '15 at 20:12








        3




        3




        That's only avoiding A being twice in memory, it does not avoid any problems caused by the Diamond. See tinyurl.com/abtjcb ; how do you implement getDepartment, that it always returns the right thing? You can't! Your design is flawed. See tinyurl.com/ccjnk6
        – Mecki
        Feb 25 '09 at 16:31




        That's only avoiding A being twice in memory, it does not avoid any problems caused by the Diamond. See tinyurl.com/abtjcb ; how do you implement getDepartment, that it always returns the right thing? You can't! Your design is flawed. See tinyurl.com/ccjnk6
        – Mecki
        Feb 25 '09 at 16:31




        5




        5




        That's what scope is for. Alternatively you can use the "using" statement in class D.
        – Mark Ingram
        Feb 26 '09 at 9:12




        That's what scope is for. Alternatively you can use the "using" statement in class D.
        – Mark Ingram
        Feb 26 '09 at 9:12




        2




        2




        Isn't this answer only valid for classes you have control over? If B and C are in a library provided by someone else, or they're part of a code base you cannot change this 'solution' doesn't work at all. It also goes against the whole principle of OOP that a base class shouldn't be concerned with the derived classes, but here B and C suddenly have to change because of some class D that was added later in the day.
        – jbx
        Oct 18 '15 at 20:12




        Isn't this answer only valid for classes you have control over? If B and C are in a library provided by someone else, or they're part of a code base you cannot change this 'solution' doesn't work at all. It also goes against the whole principle of OOP that a base class shouldn't be concerned with the derived classes, but here B and C suddenly have to change because of some class D that was added later in the day.
        – jbx
        Oct 18 '15 at 20:12












        up vote
        14
        down vote













        virtual inheritance. That's what it's there for.






        share|improve this answer

















        • 1




          Where in the inheritance hierarchy?
          – ilitirit
          Sep 26 '08 at 1:47










        • If you have B and C derived from A, and D derived from B and C, then B and C must both declare A as a virtual base. Specifically, each instance of virtual inheritance of the same class is collapsed into one class. Any non-virtual ones will not be collapsed, causing the diamond to recur.
          – coppro
          Sep 26 '08 at 2:03










        • imho, that's a solution to the problem, but not a way to avoid it...
          – Chris M.
          Sep 26 '08 at 13:02










        • While virtual inheritence is the feature for getting around the Diamond of Death problem, I think that there are better ways to work around the problem. Namely, inheriting from abstract base classes (interface classes) instead of inheriting from multiple concrete classes.
          – Nick Haddad
          Sep 26 '08 at 13:03






        • 4




          Not a complete answer.
          – Lee Louviere
          Feb 11 '11 at 23:26















        up vote
        14
        down vote













        virtual inheritance. That's what it's there for.






        share|improve this answer

















        • 1




          Where in the inheritance hierarchy?
          – ilitirit
          Sep 26 '08 at 1:47










        • If you have B and C derived from A, and D derived from B and C, then B and C must both declare A as a virtual base. Specifically, each instance of virtual inheritance of the same class is collapsed into one class. Any non-virtual ones will not be collapsed, causing the diamond to recur.
          – coppro
          Sep 26 '08 at 2:03










        • imho, that's a solution to the problem, but not a way to avoid it...
          – Chris M.
          Sep 26 '08 at 13:02










        • While virtual inheritence is the feature for getting around the Diamond of Death problem, I think that there are better ways to work around the problem. Namely, inheriting from abstract base classes (interface classes) instead of inheriting from multiple concrete classes.
          – Nick Haddad
          Sep 26 '08 at 13:03






        • 4




          Not a complete answer.
          – Lee Louviere
          Feb 11 '11 at 23:26













        up vote
        14
        down vote










        up vote
        14
        down vote









        virtual inheritance. That's what it's there for.






        share|improve this answer












        virtual inheritance. That's what it's there for.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Sep 26 '08 at 1:39









        eduffy

        29.5k88187




        29.5k88187








        • 1




          Where in the inheritance hierarchy?
          – ilitirit
          Sep 26 '08 at 1:47










        • If you have B and C derived from A, and D derived from B and C, then B and C must both declare A as a virtual base. Specifically, each instance of virtual inheritance of the same class is collapsed into one class. Any non-virtual ones will not be collapsed, causing the diamond to recur.
          – coppro
          Sep 26 '08 at 2:03










        • imho, that's a solution to the problem, but not a way to avoid it...
          – Chris M.
          Sep 26 '08 at 13:02










        • While virtual inheritence is the feature for getting around the Diamond of Death problem, I think that there are better ways to work around the problem. Namely, inheriting from abstract base classes (interface classes) instead of inheriting from multiple concrete classes.
          – Nick Haddad
          Sep 26 '08 at 13:03






        • 4




          Not a complete answer.
          – Lee Louviere
          Feb 11 '11 at 23:26














        • 1




          Where in the inheritance hierarchy?
          – ilitirit
          Sep 26 '08 at 1:47










        • If you have B and C derived from A, and D derived from B and C, then B and C must both declare A as a virtual base. Specifically, each instance of virtual inheritance of the same class is collapsed into one class. Any non-virtual ones will not be collapsed, causing the diamond to recur.
          – coppro
          Sep 26 '08 at 2:03










        • imho, that's a solution to the problem, but not a way to avoid it...
          – Chris M.
          Sep 26 '08 at 13:02










        • While virtual inheritence is the feature for getting around the Diamond of Death problem, I think that there are better ways to work around the problem. Namely, inheriting from abstract base classes (interface classes) instead of inheriting from multiple concrete classes.
          – Nick Haddad
          Sep 26 '08 at 13:03






        • 4




          Not a complete answer.
          – Lee Louviere
          Feb 11 '11 at 23:26








        1




        1




        Where in the inheritance hierarchy?
        – ilitirit
        Sep 26 '08 at 1:47




        Where in the inheritance hierarchy?
        – ilitirit
        Sep 26 '08 at 1:47












        If you have B and C derived from A, and D derived from B and C, then B and C must both declare A as a virtual base. Specifically, each instance of virtual inheritance of the same class is collapsed into one class. Any non-virtual ones will not be collapsed, causing the diamond to recur.
        – coppro
        Sep 26 '08 at 2:03




        If you have B and C derived from A, and D derived from B and C, then B and C must both declare A as a virtual base. Specifically, each instance of virtual inheritance of the same class is collapsed into one class. Any non-virtual ones will not be collapsed, causing the diamond to recur.
        – coppro
        Sep 26 '08 at 2:03












        imho, that's a solution to the problem, but not a way to avoid it...
        – Chris M.
        Sep 26 '08 at 13:02




        imho, that's a solution to the problem, but not a way to avoid it...
        – Chris M.
        Sep 26 '08 at 13:02












        While virtual inheritence is the feature for getting around the Diamond of Death problem, I think that there are better ways to work around the problem. Namely, inheriting from abstract base classes (interface classes) instead of inheriting from multiple concrete classes.
        – Nick Haddad
        Sep 26 '08 at 13:03




        While virtual inheritence is the feature for getting around the Diamond of Death problem, I think that there are better ways to work around the problem. Namely, inheriting from abstract base classes (interface classes) instead of inheriting from multiple concrete classes.
        – Nick Haddad
        Sep 26 '08 at 13:03




        4




        4




        Not a complete answer.
        – Lee Louviere
        Feb 11 '11 at 23:26




        Not a complete answer.
        – Lee Louviere
        Feb 11 '11 at 23:26










        up vote
        12
        down vote













        I'd stick to using multiple inheritance of interfaces only. While multiple inheritance of classes is attractive sometimes, it can also be confusing and painful if you rely on it regularly.






        share|improve this answer























        • C++ doesn't have interfaces.
          – Arafangion
          Apr 12 '12 at 7:40






        • 8




          @Arafangion C++ does have interfaces, although it is not a language construct as for example found in Java. Instead, they are just pure virtual base classes.
          – jlh
          Jun 11 '12 at 12:01










        • @jlh: I'll conceed that point, although I'd contend that while C++ itself doesn't have interfaces, the language does allow you to implement them.
          – Arafangion
          Jun 11 '12 at 23:58






        • 3




          I never met somebody who did not understand that it would mean inheriting pure abstract classes in this context
          – BlueTrin
          Nov 8 '14 at 9:00















        up vote
        12
        down vote













        I'd stick to using multiple inheritance of interfaces only. While multiple inheritance of classes is attractive sometimes, it can also be confusing and painful if you rely on it regularly.






        share|improve this answer























        • C++ doesn't have interfaces.
          – Arafangion
          Apr 12 '12 at 7:40






        • 8




          @Arafangion C++ does have interfaces, although it is not a language construct as for example found in Java. Instead, they are just pure virtual base classes.
          – jlh
          Jun 11 '12 at 12:01










        • @jlh: I'll conceed that point, although I'd contend that while C++ itself doesn't have interfaces, the language does allow you to implement them.
          – Arafangion
          Jun 11 '12 at 23:58






        • 3




          I never met somebody who did not understand that it would mean inheriting pure abstract classes in this context
          – BlueTrin
          Nov 8 '14 at 9:00













        up vote
        12
        down vote










        up vote
        12
        down vote









        I'd stick to using multiple inheritance of interfaces only. While multiple inheritance of classes is attractive sometimes, it can also be confusing and painful if you rely on it regularly.






        share|improve this answer














        I'd stick to using multiple inheritance of interfaces only. While multiple inheritance of classes is attractive sometimes, it can also be confusing and painful if you rely on it regularly.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Sep 26 '08 at 4:14

























        answered Sep 26 '08 at 1:49









        Bob Somers

        5,51153546




        5,51153546












        • C++ doesn't have interfaces.
          – Arafangion
          Apr 12 '12 at 7:40






        • 8




          @Arafangion C++ does have interfaces, although it is not a language construct as for example found in Java. Instead, they are just pure virtual base classes.
          – jlh
          Jun 11 '12 at 12:01










        • @jlh: I'll conceed that point, although I'd contend that while C++ itself doesn't have interfaces, the language does allow you to implement them.
          – Arafangion
          Jun 11 '12 at 23:58






        • 3




          I never met somebody who did not understand that it would mean inheriting pure abstract classes in this context
          – BlueTrin
          Nov 8 '14 at 9:00


















        • C++ doesn't have interfaces.
          – Arafangion
          Apr 12 '12 at 7:40






        • 8




          @Arafangion C++ does have interfaces, although it is not a language construct as for example found in Java. Instead, they are just pure virtual base classes.
          – jlh
          Jun 11 '12 at 12:01










        • @jlh: I'll conceed that point, although I'd contend that while C++ itself doesn't have interfaces, the language does allow you to implement them.
          – Arafangion
          Jun 11 '12 at 23:58






        • 3




          I never met somebody who did not understand that it would mean inheriting pure abstract classes in this context
          – BlueTrin
          Nov 8 '14 at 9:00
















        C++ doesn't have interfaces.
        – Arafangion
        Apr 12 '12 at 7:40




        C++ doesn't have interfaces.
        – Arafangion
        Apr 12 '12 at 7:40




        8




        8




        @Arafangion C++ does have interfaces, although it is not a language construct as for example found in Java. Instead, they are just pure virtual base classes.
        – jlh
        Jun 11 '12 at 12:01




        @Arafangion C++ does have interfaces, although it is not a language construct as for example found in Java. Instead, they are just pure virtual base classes.
        – jlh
        Jun 11 '12 at 12:01












        @jlh: I'll conceed that point, although I'd contend that while C++ itself doesn't have interfaces, the language does allow you to implement them.
        – Arafangion
        Jun 11 '12 at 23:58




        @jlh: I'll conceed that point, although I'd contend that while C++ itself doesn't have interfaces, the language does allow you to implement them.
        – Arafangion
        Jun 11 '12 at 23:58




        3




        3




        I never met somebody who did not understand that it would mean inheriting pure abstract classes in this context
        – BlueTrin
        Nov 8 '14 at 9:00




        I never met somebody who did not understand that it would mean inheriting pure abstract classes in this context
        – BlueTrin
        Nov 8 '14 at 9:00










        up vote
        5
        down vote













        Inheritance is a strong, strong weapon. Use it only when you really need it. In the past, diamond inheritance was a sign that I was going to far with classification, saying that a user is an "employee" but they are also a "widget listener", but also a ...



        In these cases, it's easy to hit multiple inheritance issues.



        I solved them by 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 get away with such an approach, without duplicating code, it's better because it's less powerful. (You can save the power for when you have no alternative.)






        share|improve this answer

















        • 1




          And what you did is that you multiplied your memory usage by a lot. No thanks.
          – spectre
          Nov 3 '15 at 19:49










        • Composition vs Inheritance. Fight!
          – Alexander Shishenko
          Feb 3 '16 at 10:45















        up vote
        5
        down vote













        Inheritance is a strong, strong weapon. Use it only when you really need it. In the past, diamond inheritance was a sign that I was going to far with classification, saying that a user is an "employee" but they are also a "widget listener", but also a ...



        In these cases, it's easy to hit multiple inheritance issues.



        I solved them by 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 get away with such an approach, without duplicating code, it's better because it's less powerful. (You can save the power for when you have no alternative.)






        share|improve this answer

















        • 1




          And what you did is that you multiplied your memory usage by a lot. No thanks.
          – spectre
          Nov 3 '15 at 19:49










        • Composition vs Inheritance. Fight!
          – Alexander Shishenko
          Feb 3 '16 at 10:45













        up vote
        5
        down vote










        up vote
        5
        down vote









        Inheritance is a strong, strong weapon. Use it only when you really need it. In the past, diamond inheritance was a sign that I was going to far with classification, saying that a user is an "employee" but they are also a "widget listener", but also a ...



        In these cases, it's easy to hit multiple inheritance issues.



        I solved them by 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 get away with such an approach, without duplicating code, it's better because it's less powerful. (You can save the power for when you have no alternative.)






        share|improve this answer












        Inheritance is a strong, strong weapon. Use it only when you really need it. In the past, diamond inheritance was a sign that I was going to far with classification, saying that a user is an "employee" but they are also a "widget listener", but also a ...



        In these cases, it's easy to hit multiple inheritance issues.



        I solved them by 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 get away with such an approach, without duplicating code, it's better because it's less powerful. (You can save the power for when you have no alternative.)







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Sep 27 '08 at 6:09







        anemptywhiteroom















        • 1




          And what you did is that you multiplied your memory usage by a lot. No thanks.
          – spectre
          Nov 3 '15 at 19:49










        • Composition vs Inheritance. Fight!
          – Alexander Shishenko
          Feb 3 '16 at 10:45














        • 1




          And what you did is that you multiplied your memory usage by a lot. No thanks.
          – spectre
          Nov 3 '15 at 19:49










        • Composition vs Inheritance. Fight!
          – Alexander Shishenko
          Feb 3 '16 at 10:45








        1




        1




        And what you did is that you multiplied your memory usage by a lot. No thanks.
        – spectre
        Nov 3 '15 at 19:49




        And what you did is that you multiplied your memory usage by a lot. No thanks.
        – spectre
        Nov 3 '15 at 19:49












        Composition vs Inheritance. Fight!
        – Alexander Shishenko
        Feb 3 '16 at 10:45




        Composition vs Inheritance. Fight!
        – Alexander Shishenko
        Feb 3 '16 at 10:45










        up vote
        3
        down vote













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


        In this the attributes of Class A repeated twice in Class D which makes more memory usage... So to save memory we make a virtual attribute for all inherited attributes of class A which are stored in a Vtable.






        share|improve this answer



























          up vote
          3
          down vote













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


          In this the attributes of Class A repeated twice in Class D which makes more memory usage... So to save memory we make a virtual attribute for all inherited attributes of class A which are stored in a Vtable.






          share|improve this answer

























            up vote
            3
            down vote










            up vote
            3
            down vote









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


            In this the attributes of Class A repeated twice in Class D which makes more memory usage... So to save memory we make a virtual attribute for all inherited attributes of class A which are stored in a Vtable.






            share|improve this answer














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


            In this the attributes of Class A repeated twice in Class D which makes more memory usage... So to save memory we make a virtual attribute for all inherited attributes of class A which are stored in a Vtable.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Jul 15 '12 at 19:19









            Tisho

            6,33853348




            6,33853348










            answered Jul 15 '12 at 19:07









            NItish

            311




            311






















                up vote
                1
                down vote













                Well, the great thing about the Dreaded Diamond is that it's an error when it occurs. The best way to avoid is to figure out your inheritance structure beforehand. For instance, one project I work on has Viewers and Editors. Editors are logical subclasses of Viewers, but since all Viewers are subclasses - TextViewer, ImageViewer, etc., Editor does not derive from Viewer, thus allowing the final TextEditor, ImageEditor classes to avoid the diamond.



                In cases where the diamond is not avoidable, using virtual inheritance. The biggest caveat, however, with virtual bases, is that the constructor for the virtual base must be called by the most derived class, meaning that a class that derives virtually has no control over the constructor parameters. Also, the presence of a virtual base tends to incur a performance/space penalty on casting through the chain, though I don't believe there is much of a penalty for more beyond the first.



                Plus, you can always use the diamond if you are explicit about which base you want to use. Sometimes it's the only way.






                share|improve this answer

























                  up vote
                  1
                  down vote













                  Well, the great thing about the Dreaded Diamond is that it's an error when it occurs. The best way to avoid is to figure out your inheritance structure beforehand. For instance, one project I work on has Viewers and Editors. Editors are logical subclasses of Viewers, but since all Viewers are subclasses - TextViewer, ImageViewer, etc., Editor does not derive from Viewer, thus allowing the final TextEditor, ImageEditor classes to avoid the diamond.



                  In cases where the diamond is not avoidable, using virtual inheritance. The biggest caveat, however, with virtual bases, is that the constructor for the virtual base must be called by the most derived class, meaning that a class that derives virtually has no control over the constructor parameters. Also, the presence of a virtual base tends to incur a performance/space penalty on casting through the chain, though I don't believe there is much of a penalty for more beyond the first.



                  Plus, you can always use the diamond if you are explicit about which base you want to use. Sometimes it's the only way.






                  share|improve this answer























                    up vote
                    1
                    down vote










                    up vote
                    1
                    down vote









                    Well, the great thing about the Dreaded Diamond is that it's an error when it occurs. The best way to avoid is to figure out your inheritance structure beforehand. For instance, one project I work on has Viewers and Editors. Editors are logical subclasses of Viewers, but since all Viewers are subclasses - TextViewer, ImageViewer, etc., Editor does not derive from Viewer, thus allowing the final TextEditor, ImageEditor classes to avoid the diamond.



                    In cases where the diamond is not avoidable, using virtual inheritance. The biggest caveat, however, with virtual bases, is that the constructor for the virtual base must be called by the most derived class, meaning that a class that derives virtually has no control over the constructor parameters. Also, the presence of a virtual base tends to incur a performance/space penalty on casting through the chain, though I don't believe there is much of a penalty for more beyond the first.



                    Plus, you can always use the diamond if you are explicit about which base you want to use. Sometimes it's the only way.






                    share|improve this answer












                    Well, the great thing about the Dreaded Diamond is that it's an error when it occurs. The best way to avoid is to figure out your inheritance structure beforehand. For instance, one project I work on has Viewers and Editors. Editors are logical subclasses of Viewers, but since all Viewers are subclasses - TextViewer, ImageViewer, etc., Editor does not derive from Viewer, thus allowing the final TextEditor, ImageEditor classes to avoid the diamond.



                    In cases where the diamond is not avoidable, using virtual inheritance. The biggest caveat, however, with virtual bases, is that the constructor for the virtual base must be called by the most derived class, meaning that a class that derives virtually has no control over the constructor parameters. Also, the presence of a virtual base tends to incur a performance/space penalty on casting through the chain, though I don't believe there is much of a penalty for more beyond the first.



                    Plus, you can always use the diamond if you are explicit about which base you want to use. Sometimes it's the only way.







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Sep 26 '08 at 2:01









                    coppro

                    12.5k35069




                    12.5k35069






















                        up vote
                        0
                        down vote













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



                        If not, use virtual functions/interfaces.






                        share|improve this answer

















                        • 1




                          "check to see if there is another way first" Why?
                          – curiousguy
                          Nov 1 '11 at 3:17















                        up vote
                        0
                        down vote













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



                        If not, use virtual functions/interfaces.






                        share|improve this answer

















                        • 1




                          "check to see if there is another way first" Why?
                          – curiousguy
                          Nov 1 '11 at 3:17













                        up vote
                        0
                        down vote










                        up vote
                        0
                        down vote









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



                        If not, use virtual functions/interfaces.






                        share|improve this answer












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



                        If not, use virtual functions/interfaces.







                        share|improve this answer












                        share|improve this answer



                        share|improve this answer










                        answered Sep 26 '08 at 12:50









                        user17720

                        211




                        211








                        • 1




                          "check to see if there is another way first" Why?
                          – curiousguy
                          Nov 1 '11 at 3:17














                        • 1




                          "check to see if there is another way first" Why?
                          – curiousguy
                          Nov 1 '11 at 3:17








                        1




                        1




                        "check to see if there is another way first" Why?
                        – curiousguy
                        Nov 1 '11 at 3:17




                        "check to see if there is another way first" Why?
                        – curiousguy
                        Nov 1 '11 at 3:17










                        up vote
                        0
                        down vote













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






                        share|improve this answer

























                          up vote
                          0
                          down vote













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






                          share|improve this answer























                            up vote
                            0
                            down vote










                            up vote
                            0
                            down vote









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






                            share|improve this answer












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







                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Feb 11 '11 at 23:24









                            Lee Louviere

                            4,2202348




                            4,2202348






























                                 

                                draft saved


                                draft discarded



















































                                 


                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function () {
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f137282%2fhow-can-i-avoid-the-diamond-of-death-when-using-multiple-inheritance%23new-answer', 'question_page');
                                }
                                );

                                Post as a guest















                                Required, but never shown





















































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown

































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown







                                Popular posts from this blog

                                Schultheiß

                                Verwaltungsgliederung Dänemarks

                                Liste der Kulturdenkmale in Wilsdruff