Mehrdeutigkeit bei Mehrfachvererbung von interfaces in C++
Machte ich einen test-code wie folgt:
#include <iostream>
using namespace std;
#ifndef interface
#define interface struct
#endif
interface Base
{
virtual void funcBase() = 0;
};
interface Derived1 : public Base
{
virtual void funcDerived1() = 0;
};
interface Derived2 : public Base
{
virtual void funcDerived2() = 0;
};
interface DDerived : public Derived1, public Derived2
{
virtual void funcDDerived() = 0;
};
class Implementation : public DDerived
{
public:
void funcBase() { cout << "base" << endl; }
void funcDerived1() { cout << "derived1" << endl; }
void funcDerived2() { cout << "derived2" << endl; }
void funcDDerived() { cout << "dderived" << endl; }
};
int main()
{
DDerived *pObject = new Implementation;
pObject->funcBase();
return 0;
}
Der Grund, warum ich schrieb diesen code zu testen, ob die Funktion funcBase() aufgerufen werden kann in eine Instanz von DDerived oder nicht. Meine C++ - complier (Visual Studio 2010) gab mir eine Fehlermeldung kompilieren, wenn ich versuchte, um diesen code zu kompilieren. Meiner Meinung nach, ist es kein problem, in diesem code, denn es ist sicher, dass die Funktion funcBase()
umgesetzt werden (also überschrieben) in einigen abgeleiteten Klasse von der Schnittstelle DDerived
, denn es ist rein virtuell. In anderen Worten, jedes Zeiger-variable vom Typ Implementation *
sollte verbunden sein mit einer Instanz einer Klasse, die Implementierung und überschreiben der Funktion funcBase()
.
Meine Frage ist, warum der compiler mir eine solche Fehlermeldung? Warum das C++ - syntax definiert, wie, dass; D. H., zur Behandlung von diesem Fall als ein Fehler? Wie kann ich den code ausgeführt? Ich möchte Mehrfachvererbung von Schnittstellen. Natürlich, wenn ich "virtuellen öffentlichkeit" oder re-deklarieren Sie die Funktion funcBase()
im Implementation
wie
interface DDerived : public Derived1, public Derived2
{
virtual void funcBase() = 0;
virtual void funcDDerived() = 0;
};
dann läuft alles ohne problem.
Aber ich will nicht zu tun, und auf der Suche nach mehr bequeme Methode, da die virtuelle Vererbung kann sich verschlechtern die Leistung und die re-Erklärung ist so mühsam, Sie zu tun, wenn die Vererbung Beziehungen zwischen Klassen sind sehr Komplex. Gibt es irgendwelche Methoden, damit mehrfache Vererbung von Schnittstellen in C++ zu verwenden, mit virtuellen Vererbung?
- Meine psychischen Kräfte sagen mir, dass der Fehler Aufruf mehrdeutig Basisklasse Funktion.
- Aber es ist nicht eine base-Klasse, es ist entweder ein base-Schnittstelle oder eine Basis-Struktur.
- mögliche Duplikate von C++ - Mehrfachvererbung - warum Sie nicht arbeiten?
- "es ist sicher, dass die Funktion funcBase() implementiert (und damit überschrieben) in einige abgeleitete Klasse das interface Implementation" - das ist wahr. Jedoch, das problem in Ihrem Fall ist, dass es mehr als einen, und der compiler kann nicht entscheiden, welche Sie wollen für Sie. Sie müssen springen durch einige Reifen (zum Beispiel durch den Umbau der Zeiger auf die Basis, die Sie wollen) zu machen, die Wahl ausdrücklich an.
- Da Ihr
interface
s sind eigentlichstruct
s können Sie weglassen diepublic
beim vererben. - Was ich jedoch argumentiert, dass eine der beiden Möglichkeiten sollte man eventuell identisch für den Fall, dass die Funktion ist rein virtuell, so denke ich, kann es gut sein, wenn der compiler wissen das....
Du musst angemeldet sein, um einen Kommentar abzugeben.
Als Sie definiert haben, ist Ihr Objekt-Struktur sieht wie folgt aus:
Der wichtige Punkt hier ist, dass jede Instanz von
Implementation
enthält zwei völlig separate Instanzen vonBase
. Sie bietet eine überschreibung derBase::funcBase
, weiß aber nicht, ob Sie versuchen, zu überschreibenfuncBase
für dieBase
geerbt Sie durchDerived1
oder dieBase
geerbt Sie durchDerived2
.Ja, die saubere Art und Weise damit umzugehen, ist die virtuelle Vererbung. Dies wird sich ändern Sie Ihre Struktur, sodass es nur eine Instanz von Base:
Dies ist fast zweifellos, was Sie wirklich wollen. Ja, es hat einen guten Ruf für die performance-Probleme in den Tagen des primitiven Compiler und 25 MHz 486 s und so. Mit einem modernen compiler und Prozessor, sind Sie unwahrscheinlich, um auf ein problem stoßen.
Andere Möglichkeit wäre eine Art template-basierte alternativen, aber die neigt zu durchdringen den rest des Codes, D. H., statt der übergabe eines
Base *
Sie eine Vorlage schreiben, die Arbeit mit etwas, das bietet die Funktionen A, B und C, dann pass (äquivalent)Implementation
als template-parameter.Die Sprache C++ ist so konzipiert, dass Sie in Ihrem ersten Ansatz ohne virtuelle Vererbung gibt es zwei Eltern-Kopien von der Methode und es kann nicht herausfinden, was zu nennen.
Virtuelle Vererbung ist die C++ - Lösung zu vererben die gleiche Funktion aus mehreren Unterseiten, also ich würde einfach vorschlagen mit diesem Ansatz.
Abwechselnd haben Sie in Betracht gezogen, nur nicht Erben die gleiche Funktion von mehreren Basen? Haben Sie wirklich eine abgeleitete Klasse, die Sie benötigen, um in der Lage sein zu behandeln, wie
Derived1
oderDerived2
ODERBase
je nach Kontext?In diesem Fall erarbeiten ein konkretes problem eher als ein erfundenes Beispiel, kann helfen, eine bessere design.
Base
,Derived
, undDerived2
sind nicht alle orthogonal Klassen direkt vererbtDDerived
.Dieser erstellt einen Zeiger vom Typ DDerived zu einer Umsetzung. Wenn Sie mit DDerived Sie wirklich einfach nur einen Zeiger auf eine Schnittstelle.
DDerived weiß nicht, über die Umsetzung der funcBase aufgrund der Mehrdeutigkeit der mit funcBase definiert sind, die in beiden Derived1 und Derived2.
Dies hat eine erbschaft Diamant-das ist das, was wirklich das problem verursacht.
http://en.wikipedia.org/wiki/Diamond_problem
Hatte ich auch die " Schnittstelle "keyword" Sie haben dort
es ist eine ms-spezifische Erweiterung, die erkannt wird durch visual studio
Ich denke, dass C++ - Standard 10.1.4 - 10.1.5 kann Ihnen helfen, zu verstehen, die ein problem in deinem code.
So fügen Sie nur-Qualifikanten beim Aufruf von pObject->funcBase() oder lösen von Mehrdeutigkeiten in einer anderen Art und Weise.
Aktualisiert: Auch sehr hilfreiche Lektüre sein wird 10.3 Virtuelle Funktionen Standard.
Haben ein schönes Wochenende 🙂