2009-07-07 5 views
10

Um klar zu sein, ich frage nicht, ob/warum Mehrfachvererbung gut oder schlecht ist. Ich habe viele Argumente von beiden Seiten dieser Debatte gehört.Wann kann Mehrfachvererbung die einzig vernünftige Lösung sein?

Ich frage mich, ob es irgendeine Art von Design-Problem oder Szenario in C++ gibt, in denen mehrere Vererbung ist entweder die einzige Möglichkeit, etwas zu erreichen, oder zumindest ist der beste Weg gegenüber allen anderen Alternativen zu dem Punkt, dass es Es würde keinen Sinn ergeben, etwas anderes zu betrachten.

Offensichtlich gilt diese Frage nicht für Sprachen, die keine Mehrfachvererbung unterstützen.

+0

Eine ähnliche Frage: http://stackoverflow.com/questions/573913/a-use-for-multiple-inheritance –

Antwort

10

Sie können policy-based design nicht ohne Mehrfachvererbung tun. Wenn also richtlinienbasiertes Design der eleganteste Weg ist, um Ihr Problem zu lösen, bedeutet dies, dass Sie mehr Vererbung benötigen, um Ihr Problem zu lösen, als alle anderen Optionen.

Mehrfachvererbung kann sehr nützlich sein, wenn sie nicht missbraucht wird (wie alles in jeder Sprache).

+2

dies, dass die richtlinienbasierte Design bedeuten würde, ist einfach nicht möglich, in einer Sprache, wie Java, oder gibt es Möglichkeiten, um es zu umgehen? –

+0

Tatsächlich zeigt der verknüpfte Artikel an, dass Mehrfachvererbung nur das häufigste Implementierungsmuster (mit einigen signifikanten Vorteilen) ist, nicht dass es absolut erforderlich ist. – GalacticCowboy

+0

@ Jeff L: Die Klasse 'Proxy' in Java kann als Workaround verwendet werden. – finnw

5

Es gibt eine Situation, in der Sie von einer Klasse erben und vielleicht ein oder zwei Interfaces in Java implementieren würden. Das ist etwas, was Sie mit Mehrfachvererbung in C++ lösen würden, denke ich.

2

Ich habe auf Java-Schnittstellen gelesen, und so weiter, um eine bessere Idee in Bezug auf die Antwort auf diese Frage zu bekommen. Die Idee hinter einer Schnittstelle besteht darin, eine abstrakte Klasse zu erstellen, die als Vorlage für eine andere Klasse dient. Der Vorteil hierbei ist, dass die Vorlagen innerhalb einer konkreten Klasse kombiniert werden können. Für Beispiel-

Eltern Klassen- lebensmittel Subclass- Coffee Subclass- Bäckerei

Mit diesem Vererbungsbaum kann ein Foods eine Bäckerei oder ein Coffee-Shop, aber nicht beides. Aber was würden wir Starbucks nennen?

bessere Art und Weise, IMO-

Eltern Class- Foods Interface- Coffee Interface- Bäckerei

public class Starbucks Foods erweitert implementiert Coffeeshop, Bäckerei {...}

Sie über Ich muss ein bisschen Java wissen, um das zu verstehen, aber ich habe es getan. Schnittstellen sind ziemlich elementar, IMO.

Als weitere Überlegungen, vielleicht Schnittstellen sind entworfen, um zu gehorchen "Wiederhole dich nicht." Offensichtlich, jetzt wo ich es erwähne.

3

Mehrere Vererbung ist nützlich, wenn Sie erben müssen Verhalten, nicht nur Vertrag. Wie andere Sprachen jedoch zeigen, ist die Mehrfachvererbung nicht die einzige Möglichkeit, dieses Problem zu lösen, und zwar auf Kosten der Vertie- fung des Vererbungsbaums. Daher können Szenarien, in denen Sie müssen und nur Mehrfachvererbung verwenden, wäre ziemlich selten.

0

Wie haben sich auf den anderen Antworten gesagt:

  • rein virtuelle Basisklassen als „Schnittstellen“ Verwendung, wie in Java (http://en.wikipedia.org/wiki/Interface_(Java)), ist dies eine sehr häufige O.Ö. ist Muster in allen O.O.Sprachen, nicht nur Java

  • Polizei-basierte Design

Aber auch zu tun:

  • Um eine Klasse mit mehreren Mixins (http://en.wikipedia.org/wiki/Mixin) zu komponieren; Ich halte dies für eine sehr gute Nutzung der Mehrfachvererbung, um die Wiederverwendung von Code zu erreichen!
3

C++ Streams verwenden Mehrfachvererbung: istream und ostream sind beide Elternteile von iostream. Da sie beide von ios_base erben, haben Sie einen Diamanten.

Es ist die einzige "vernünftige" Lösung in dem Sinne, dass es für die Streams Teil der Standard-Bibliotheken nicht sinnvoll wäre, die gleiche Linie wie die Algorithmen und Sammlungen zu nehmen. Daher verhält sich ostream polymorph, anstatt eine "duckenartige" Schnittstelle wie Iterator (*) zu sein.

Sobald Sie dynamischen Polymorphismus haben, benötigen Sie mehrere Vererbung, um mehr als eine Schnittstelle gleichzeitig zu implementieren.

(*) Vermutlich ist dies, weil alles andere ein Trümmerhaufen wäre. Sie müssen in der Lage sein, tatsächliche Funktionen zu schreiben, die Streams manipulieren, anstatt Benutzer zu zwingen, Vorlagen überall zu haben. Dies ist, weil es üblich ist, zu schreiben "einige Stream, ich weiß nicht, was bis zur Laufzeit", aber nicht "einige Sammlung zu manipulieren, ich weiß nicht, was bis zur Laufzeit".

1

Wenn Sie wollen Funktionalität erben anstatt Rolle, Fall in Punkt boost::noncopyable (andere Sprachen, die dies unterstützen (im Gegensatz zu Java und C#) nennen dies eine mixin).

0

Wenn Sie zwei oder mehr Klassenhierarchien von Drittanbietern kombinieren müssen, für die jeweils Objekte aus der eigenen Basisklasse der Hierarchie abgeleitet werden müssen, führt die fehlende Mehrfachvererbung dazu, dass Ihr Code komplex und findig wird.

namespace Object_Database { 
    class Object { 
     public: 
     virtual void store() ; 
     virtual void fetch() ; 
    }; 
} 

namespace Reflectives { 
    class Object { 
     public: 
     virtual std::vector<std::string> > membernames(); 
     virtual std::vector<std::string> > methodnames(); 
    }; 
} 

Die erste Hierarchie können Benutzer Objekte erstellen, die zu und von einer Objektdatenbank serialisiert werden kann, und verlangt, dass alle solche Objekte aus der Klasse Object_Database abgeleitet werden :: Object. Die zweite Hierarchie ermöglicht es Benutzern, Objekte zu erstellen, die zur Laufzeit nach den Namen ihrer Mitglieder abgefragt werden können, und erfordert, dass alle diese Objekte von Reflectives :: Object abgeleitet werden.

Wenn Sie Objekte benötigen, die beides können, müssen Sie nur schreiben:

class ReflectivePickle : 
    public Object_Database::Object, 
    public Reflectives::Object { 
    // ... 
    }; 

Die anderen Lösungen unzumutbar sind.

0

Ich neige dazu, mehrfache Vererbung in C++ zu verwenden, wenn die Basisklassen "Schnittstellenklassen" sind, dh Basisklassen, in denen alle Methoden rein virtuell sind, keine Implementierungen haben [erinnern Sie sich noch eine Implementierung definieren können, aber Sie müssen sie aufrufen explizit], und es gibt keine Datenelemente. Sehr ähnlich zu "Schnittstellen" in Java oder (von dem, was ich höre) C#.

Um Polymorphie in C++ zu verwenden, können Sie keine Komposition verwenden, Sie müssen (öffentliche) Vererbung verwenden.

Wenn also die Klasse Bar (öffentlich) von Printable und Serializable erbt, kann ich das Objekt wie ein druckbares Objekt, ein serialisierbares Objekt oder ein Bar-Objekt (mit Zeigern oder Referenzen) behandeln.

Mit Zusammensetzung, können Sie das nicht tun.

0

Wenn Sie eine schöne Implementierung von Multiple Inheritance sehen möchten, überprüfen Sie Eiffel. Sie lösen das Diamant Problem durch Feature Umbenennung, weit einfacher als Rahmen Auflösung und unterstützt sogar die direkte wiederholte Vererbung, so dass:

A vererben B, B, B

wenn die Notwendigkeit entsteht diese Art der Vererbung zu verwenden.

Ihre Kernel-Bibliothek ist Open Source und mehrfache Vererbung wird ausgiebig verwendet, wenn Sie Beispiele sehen möchten.

http://sourceforge.net/projects/eiffelstudio/files/

Verwandte Themen