1

I am looking for a useful example of multiple inheritance in C++ and found an example for Window-creation here: A use for multiple inheritance? and modified it a bit. It conceptually looks like this:

class Window
class Skinable  // abstract
class Draggable // abstract
class DraggableSkinnableWindow : Window, Draggable, Skinnable

I think this is supposed to be a good example where MI makes sense. Since it doesn't make sense to implement a class of Skinable, it should be defined abstract.

Now: How would this look like if I would not use the concept of MI. I would have used a simple hierarchical structure like this:

class  Window
class Dragable : public Window
class Skinable : public Dragable
class DraggableSkinnableWindow : Skinnable

I still want Dragable and Skinable to be abstract as well but is that even possible? Is the second example even a good solution for the same context but not using MI?

Thank you in advance!

Community
  • 1
  • 1
  • 3
    Yes, Abstract classes may even have complete implementations provided, and still be abstract. You are defining an abstraction, which you deem incomplete, but incomplete doesn't mean completely devoid of substance. – StoryTeller - Unslander Monica Jun 02 '15 at 10:25
  • 1
    Your single-inheritance-idea sounds conceptually wrong. I can imagine draggable GUI elements other than whole windows (same for skinable) – deviantfan Jun 02 '15 at 10:25
  • If a language doesn't provide MI this is usually solved by implementing interfaces. – Hatted Rooster Jun 02 '15 at 10:25
  • @JameyD Since both Draggable and Skinnable are abstract in his example, this is essentially. The user of abstract classes as interfaces. – Aluan Haddad Jun 02 '15 at 10:28
  • @StoryTeller Are you sure? How do you define abstract class in c++, I always thought you need to have at least one pure virtual function in a class to make it abstract. Thus, you cannot have a complete definition provided. They may have definitions provided but not for everything. Or perhaps you meant that, in other words, and I failed to grasp it. – luk32 Jun 02 '15 at 10:55
  • 1
    @luk32 I think he meant the following: While an abstract class has a abstract method, it may also have other non-abstract methods. Just because it is an abstract class it does not mean that all methods have to be abstract. – 463035818_is_not_an_ai Jun 02 '15 at 11:52
  • @luk32 In this context I like to use the term Interface for "pure abstract classes" (i.e. really only abstract methods), even though in C++ interfaces do not really exists (well, they do exist, but there is no need to call them like this) – 463035818_is_not_an_ai Jun 02 '15 at 11:54
  • @luk32, I meant what tobi303 understood. Since quite a few abstract classes are only abstract due to a pure virtual destructor (which still has to be defined), there is more concrete than abstract in such classes IMHO. – StoryTeller - Unslander Monica Jun 02 '15 at 11:59
  • @StoryTeller Oh, sure you are right, I was thinking for a moment, that you meant that they have complete implementations for everything. It is about the implicit quantificator in "*Abstract classes may even have complete implementations provided,*" I thought you meant for "everything" while you meant "anything". – luk32 Jun 02 '15 at 13:59

3 Answers3

1

While your example is a solid use case for multiple inheritance, I disagree with the assertion that it does not make sense for Skinnable to have an implementation. Rather, as @devianfan alluded to in his comment, your single inheritance alternative fails to model the conceptual taxonomy.

It is about cross axial classifications. A window is both skinabble and draggable but neither of these qualities are codependent.

Consider that, as suggested by your example domain, your application code consists of a collection of graphical user interface elements. You might want to perform perform operations on subgroups of them based on their capabilities. For example you might manipulate the appearance of all skinnable elements based on some customization. On the other hand, there are probably elements of your GUI which are draggable and should be notified on certain user input events. A window is a good example of something which falls into both categories.

Aluan Haddad
  • 29,886
  • 8
  • 72
  • 84
1

I think this is supposed to be a good example where MI makes sense.

It does, at long as Window, Draggable, Skinnable do not share common ancestor, at least other than pure abstract, otherwise you would need virtual inheritance.

Since it doesn't make sense to implement a class of Skinable, it should be defined abstract.

It can make sense, for example defining a property skin + setters and getters. You seem to be confusing abstract classes and pure abstract classes. Abstract classes have at least one pure virtual function, which means you cannot instantiate them. Pure abstract classes do not have any implementation of any method, they contain only pure virtual functions, and are often used as a realization interface concept in c++.

How would this look like if I would not use the concept of MI. Is the second example even a good solution for the same context but not using MI?

You cannot do it properly. c++ does not differentiate between classes and interfaces (as it does not provide such concept on language level). It is the same as stripping java or c# of interfaces. It would be possible if you provided all the compounds by hand i.e. Skinnable, Draggable bases, would produce SkinnableDraggable and/or DraggableSkinnable (which would probably be equivalent) dervided classes. This is quite a killer.

Your example, as others mentioned completely mixes unrelated concepts. E.g. Your Draggables and Skinnables must be Windowses. This is not obvious, and certainly not correct in general.

luk32
  • 15,812
  • 38
  • 62
  • "You cannot do it properly. c++ does not differentiate between classes and interfaces" this statement is not correct. C++ allows a class to inherit from an arbitrary number of classes. On the contrary, Java and C# interfaces are stripped down versions of C++ abstract classes. While having the concept of an interface formalized at the language level is semantically enriching, C++ is not restricted in terms of implementing this pattern. – Aluan Haddad Jun 02 '15 at 11:52
  • I am not sure which statement you are referring to. "You cannot do it properly." - well, you can't given no multiple inheritance, can you? That was the premise of the question. "*c++ does not differentiate between classes and interfaces*". I believe I made the same points as you did. 1. It is not formalized. 2. It uses `class` to implement the concept, I gave ABC as an example. Non-virtual interfaces also use classes. Those are two most popular realizations of interfaces in c++. If you say you could do it with out MI, I'd like to see an example. – luk32 Jun 02 '15 at 12:49
  • I am sorry, but did you read the question? "*Is the second example even a good solution for the same context **but not using MI**?*", the premise of the question is not to use it. – luk32 Jun 02 '15 at 13:55
1

I would probably go like this

 class Window
 class Draggable : public virtual Window
 class Skinnable : public virtual Window
 class DraggableSkinnableWindow : Draggable, Skinnable

And provide default implementation in the pure virtual methods contained in Draggabel and Skinnable separately

class Draggable : public virtual Window {

    virtual void aMethod() = 0;
    void aMethodDefaultImplementation() = { //...// }; 
}

then inside DraggableSkinnable you have two options:

virtual void aMethod() = { aMethodDefaultImplementation() };

or

virtual void aMethod() = {// ...non-default implementation... //};

This has the benefit of providing a default implementation if you need one (as if aMethod was not pure virtual) but forcing you to ask for that explicitly (because it is purely virtual).

Emerald Weapon
  • 2,392
  • 18
  • 29
  • Why would you make anything `Skinnable` or `Draggable` a `Window`, seems like a strong assumption. – luk32 Jun 02 '15 at 14:01
  • That simply appeared to me to be the intention of the OP. – Emerald Weapon Jun 02 '15 at 14:04
  • I don't think so. You still have multiple inheritance, and you introduce concretizations (something that looks more like `SkinnableWindow)`. Of course it can be reasonable, I just don't see it, however you do and I might very well be wrong =) – luk32 Jun 02 '15 at 14:14