0

Is there any way to avoid diamond problem form built in a class where I can't inherit virtually like below?

  class Widget
  {
     // Built in class can't be modified
     public:
        bool draw();
  };

  class Button : public Widget
  {
     // Built in class can't be modified
     // Not able to put virtual inheritance for Widget Class
  };

  class MyOwnSpecialWidget : public Widget
  {
     // Some special treatment for non container widgets
  };


  class CustomButton : public Button, public MyOwnSpecialWidget
  {
     // So here the copy of Widget is coming form both Button
     // and MyOwnSpecialWidget class.
  };

So, what is the way to get only one copy of Widget class in CustomButton class?

Dilip Raj Baral
  • 3,060
  • 6
  • 34
  • 62
Swapnil
  • 389
  • 5
  • 22
  • 2
    `template class MyOwnSpecialWidgetX : public Base { ... }; typedef MyOwnSpecialWidgetX MyOwnSpecialWidget; class CustomButton : public MyOwnSpecialWidgetX – melpomene Jul 29 '17 at 17:38
  • @Ron then how the feature of `MyOwnSpecialWidget` be a part of `CustomButton` – Swapnil Jul 29 '17 at 17:45
  • 1
    @swapnil: `MyOwnSpecialWidget` might be better as a decorator than as a base class. – cHao Jul 29 '17 at 17:57
  • Can you please explain the idea you need this for. Are you using some 3rd party GUI library and want to extend it or just building your own? In case you're inventing it - there's a better approach for combining UI functionality without using inheritance, basically it's a mix of aggregation and MVC patterns. – Mr D Jul 29 '17 at 18:35
  • I basically pasted @melpomene 's comment into a compiler (and added some public constructors) to verify it. Are you good swapnil? Do you need more info on what it's doing, and why? – Kenny Ostrom Jul 30 '17 at 13:30
  • @Kenny Ostrom yes i am good, I would really appreciate if you provide some more details. – Swapnil Jul 30 '17 at 15:01
  • Basically you have to duplicate the same Widget overrides in two places. Once for Widget->MyWidget, and once for Widget->Button->MyButton. But literally duplicating the code is a HORRIBLE idea, so that's where the template comes in. It tells you how to override the widget, and you use the same template source when declaring both of your custom classes. – Kenny Ostrom Jul 30 '17 at 15:42
  • @KennyOstrom or @melpomene it seems that it also works without the `typedef` you mentioned, what is the role of it? and In this case the `Button` becomes indirect base class of my `CustomButton` which causes me to make an indirect call to `Button`'s constructor and might need to write many template specialisation in `CustomButton` for different Widgets which needs to be inherit by `CustomButton`. – Swapnil Jul 31 '17 at 06:46
  • The typedef is for your convenience, so that when you actually use those classes, the code will look exactly like you expect, and you don't have to even know there was a template involved. If there are a bunch of different widget types, then using template syntax may be easier. – Kenny Ostrom Jul 31 '17 at 16:39
  • As always, good naming will help tremendously, but there wasn't much opportunity, given the completely generic class names in the example, and not knowing anything about why/hor the widget is being modified, so there was no way to come up with a good name to reflect that. – Kenny Ostrom Jul 31 '17 at 16:41
  • I do not understand your comment about "indirect call to button's constructor" because button is a parent, so of course you call its constructor. – Kenny Ostrom Jul 31 '17 at 16:43
  • @KennyOstrom i think `Button` is not a direct parent of `CustomButton` class and i can not call its constructor from the same. I have to pass arguments required by `Button` to `MyOwnSpecialWidgetX` and then it can pass those arguments to `Button` class. If i try to do that i get the error that type `Button` is not a direct base of `CustomButton` – Swapnil Aug 01 '17 at 07:53
  • Okay, I understand. Is that a problem? If it is too cumbersome, you could consider cHao's comment, and search for "c++ template decorator". I think that changes more code, but gets around this. – Kenny Ostrom Aug 01 '17 at 12:50
  • @cHao or @KennyOstrom finally i turn my mind to try out decorator, but will it be easy to implement decorator if the `draw()` method from the topmost base class `(Widget)` is protected. Because if its protected then i cant call draw method on `Button` form the decorator class. By the way I am using _`gtkmm-3.0`_ tool kit for this. – Swapnil Aug 03 '17 at 17:53
  • You can use `draw` if you inherit from the class you're decorating, as long as nothing else has privatized it. – cHao Aug 03 '17 at 18:04

0 Answers0