C++ und Java : die Verwendung von virtuellen Basisklasse
Habe ich einige Zweifel beim Vergleich von C++ und Java Mehrfachvererbung.
-
Sogar Java verwendet mehrere, multi-level-Vererbung durch Schnittstellen - aber warum nicht es verwenden, so etwas wie eine virtuelle Basisklasse in C++ ? Ist es, weil die Mitglieder einer java-Schnittstelle gewährleistet eine Kopie im Speicher (Sie sind public static final), und die Methoden sind nur deklariert und nicht definiert ist ?
-
Abgesehen von spart Speicher, ist es eine andere Verwendung von virtuellen Klassen in C++ ? Gibt es irgendwelche Einschränkungen, wenn ich vergesse, um dieses feature in meinem Mehrfachvererbung Programme ?
-
Dieser ist etwas philosophisch - aber warum nicht die C++ - Entwickler machte es zu einem Standard zu machen, jede Basisklasse virtuell ? Was war die Notwendigkeit der Bereitstellung von Flexibilität ?
Beispiele geschätzt werden. Danke !!
- Was meinst du mit "virtual base class" in C++? Eine Klasse, die mindestens eine rein virtuelle Funktion (z.B. virtual void booga() = 0; )?
- publib.boulder.ibm.com/infocenter/comphelp/v7v91/...
- Eine Basis Klasse mit mindestens einer virtuellen Funktion (nicht unbedingt rein virtuelle Funktion) ist eine virtuelle Basisklasse. Eine Basis Klasse mit mindestens einer rein virtuellen Funktion aufgerufen wird als abstrakte Basisklasse.
- Wir sollten etwas präziser sein. C++'s "virtual base class" ist gut definiert, um eine Basis-Klasse, praktisch vererbt werden. Ihre erste Begriff wäre besser, als "polymorphe Basisklasse".
Du musst angemeldet sein, um einen Kommentar abzugeben.
1) Java-Schnittstellen dont Attribute haben. Ein Grund für die virtuelle Basis-Klassen in c++ ist, um doppelte Attribute und alle Schwierigkeiten.
2) Es ist mindestens eine leichte performance-Einbußen für die Verwendung von virtuellen Basisklassen in c++. Auch die Konstrukteure werden so kompliziert, dass es wird darauf hingewiesen, dass virtuelle Basisklassen haben nur no-argument-Konstruktoren.
3) Genau, weil der c++ Philosophie: Man sollte nicht verlangen, eine Strafe für etwas, was man nicht brauchen kann.
Sorry - kein Java-Programmierer, so kurz auf details. Noch, virtuelle Basen sind eine Verfeinerung der Mehrfachvererbung, die Java-Designer immer wieder verteidigt ommiting auf der Grundlage, dass es übermäßig kompliziert und wohl auch fehleranfällig.
virtuellen Basen sind nicht nur zum speichern von Speicher - die Daten weitergegeben, die durch die verschiedenen Objekte Erben von Ihnen, so die abgeleitete Typen könnten es verwenden, um koordinieren Ihr Verhalten in irgendeiner Weise. Sie sind nicht nützlich, alle, die oft, aber als Beispiel: Objekt-IDS, wo Sie wollen, ein id-pro die meisten abgeleiteten Objekts, und nicht damit rechnen, dass alle Unterobjekte. Ein weiteres Beispiel: Sicherstellung, dass eine mehrfach abgeleitete Typ kann eindeutig anzeigen /konvertiert einen Zeiger auf base, es zu halten einfach zu bedienen, Funktionen operieren auf der Basis geben, oder zum speichern in Container Base*.
Als C++ ist derzeit Standardisiert, eine Art die sich aus zwei-Klassen können in der Regel erwarten, dass Sie unabhängig voneinander operieren und wie Objekte dieses Typs neigen zu tun, wenn auf dem stack oder heap. Wenn alles virtuelle, plötzlich diese Unabhängigkeit wird stark abhängig von den Arten, aus denen Sie abgeleitet werden - alle Arten von Interaktionen werden die Standard -, und die Ableitung selbst wird immer weniger nützlich. Also, Ihre Frage ist warum machen Sie nicht den Standard-virtual - auch, weil es weniger intuitiv, mehr gefährliche und fehleranfällige der beiden Modi.
1.Java Mehrfachvererbung bei interfaces verhält sich die meisten wie die virtuelle Vererbung in C++.
Genauer gesagt, zu implementieren java-wie Vererbung-Modell in c++ müssen Sie die Verwendung von c++ virtuelle Basisklassen.
Jedoch einer der Nachteile von c++ virtuelle inheriritance (außer der kleine Speicher und performance Strafe) ist die Unmöglichkeit der static_cast<> von der Basis zu abgeleitet, so dass rtti (dynamic_cast) verwendet werden müssen
(oder kann man Sie "von hand gemacht" virtuelle casting-Funktionen für die Kind-Klassen, wenn eine Liste mit
solche Kind-Klassen im Voraus bekannt sind)
2.wenn Sie vergessen "virtuellen" qualifier in erbschaft-Liste, führen in der Regel zu compiler-Fehler
da jede casting-frome fährt um Basisklasse wird zweigeteilte
3.Philosophische Fragen sind in der Regel ziemlich schwierig zu beantworten... c++ ist eine multiparadigm (und multiphilosophical) Sprache und nicht anderen philosophischen Entscheidungen. Sie dürfen virtuelle Vererbung, Wann immer möglich, in der Sie eigene Projekte, und (Sie sind rioght) es hat einen guten Grund. Aber so ein maxima kann nicht akzeptabel sein, für andere, so dass die Universelle c++ - Werkzeuge (standard-und anderen weit verbreiteten Bibliotheken) sollte (wenn möglich) frei von bestimmten philosophischen Konventionen.
Ich arbeite an einem open source Projekt, welches im Grunde ist das übersetzen eine große C++ - Bibliothek für Java. Das Objekt-Modell von der ursprünglichen Kreatur in C++ kann ziemlich kompliziert manchmal. Mehr als notwendig, würde ich sagen... das war mehr oder weniger das motto von Java-Designer... naja... das ist ein anderes Thema.
Der Punkt ist, dass ich geschrieben habe, ein Artikel, der zeigt, wie Sie können, zu umgehen, type erasure in Java. Der Artikel erklärt auch, wie es getan werden kann, und, am Ende, wie Sie Ihre source-code kann schließlich ähneln sich C++ sehr eng.
http://www.jquantlib.org/index.php/Using_TypeTokens_to_retrieve_generic_parameters
Eine unmittelbare Folgerung aus der Studie, die ich getan habe, ist, dass es möglich wäre zu implementieren, virtuelle Basisklassen in Ihrer Anwendung, ich meine: nicht in Java, nicht in der Sprache, sondern in Ihrer Anwendung, über einige tricks, oder eine Menge tricks, um genauer zu sein.
Falls Sie Interesse haben für eine solche Art von schwarzer Magie, die folgenden Zeilen kann nützlich sein für Sie irgendwie. Ansonsten sicherlich nicht.
Ok. Gehen wir weiter.
Gibt es mehrere Schwierigkeiten, in Java:
1. Type-erasure (gelöst in dem Artikel)
2. javac wurde nicht entwickelt, um zu verstehen, was eine virtuelle Basisklasse sein würden;
3. Auch mit tricks, die Sie nicht in der Lage sein zu umgehen Schwierigkeit #2, weil diese Schwierigkeit scheint bei der Kompilierung.
Wenn Sie möchten, um zu verwenden, virtuelle Basisklassen, können Sie es, mit Scala, die im Grunde gelöst Schwierigkeit #2 von genau erstellen Sie einen weiteren compiler, der es vollständig versteht, einige weitere anspruchsvolle Objekt-Modelle, würd ich sagen.
wenn Sie möchten, um zu erkunden, meine Artikel und versuchen Sie zu "circunvent" virtuelle Basisklassen in Java (kein Scala), Sie könnten etwas tun, wie ich unten erklären:
Nehme an, dass Sie so etwas wie dies in C++:
Könnte es übersetzen, um so etwas in Java:
OK. Was passiert, wenn Sie instanziieren Erweitert wie unten?
Gut.. im Grunde werden Sie in der Lage sein, um loszuwerden, type erasure und wird in der Lage sein zu Erhalten, geben Informationen von der Basis in Ihrer Klasse Erweitert wird. Siehe meinen Artikel für eine umfassende Erklärung für die schwarze Magie.
OK. Sobald Sie den Typ der Basis innen Erweitert, die Sie instanziieren können eine konkrete implementation der Virtuellen.
Beachten Sie, dass bei der Kompilierung javac überprüfen können, Typen für Sie, wie im Beispiel unten:
Gut... trotz aller Anstrengungen, es zu implementieren, am Ende sind wir so schlecht da, was einen exzellenten compiler wie scalac viel besser als wir, in allem tut es seinen job bei der Kompilierung.
Ich hoffe, es hilft... wenn nicht, verwechselt Sie schon!