C++ Mehrfachvererbung mit interfaces?
Grüße alle,
Ich komme aus der Java-hintergrund und ich habe Schwierigkeiten mit Mehrfachvererbung.
Ich habe ein interface namens IView die init () - Methode.Ich will leiten Sie eine neue Klasse namens PlaneViewer Implementierung der obigen Schnittstelle und erweitern eine andere Klasse. (QWidget).
Meine Implementierung ist als:
IViwer.h (nur Header-Datei , keine CPP-Datei) :
#ifndef IVIEWER_H_
#define IVIEWER_H_
class IViewer
{
public:
//IViewer();
///virtual
//~IViewer();
virtual void init()=0;
};
#endif /* IVIEWER_H_ */
Meine abgeleitete Klasse.
PlaneViewer.h
#ifndef PLANEVIEWER_H
#define PLANEVIEWER_H
#include <QtGui/QWidget>
#include "ui_planeviewer.h"
#include "IViewer.h"
class PlaneViewer : public QWidget , public IViewer
{
Q_OBJECT
public:
PlaneViewer(QWidget *parent = 0);
~PlaneViewer();
void init(); //do I have to define here also ?
private:
Ui::PlaneViewerClass ui;
};
#endif //PLANEVIEWER_H
PlaneViewer.cpp
#include "planeviewer.h"
PlaneViewer::PlaneViewer(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
}
PlaneViewer::~PlaneViewer()
{
}
void PlaneViewer::init(){
}
Meine Fragen sind:
- Ist es notwendig zu erklären, die Methode init() in PlaneViewer-Schnittstelle auch , denn es ist bereits definiert, die in IView?
2.Ich kann nicht complie obigen code Fehler geben :
PlaneViewer]+0x28): undefined reference to `Typinformation für IViewer'
collect2: ld zurückgegeben, 1 exit status
Muss ich haben-Implementierung für IView in der CPP Datei (weil alles was ich will ist eine Schnittstelle,nicht die Implementierung) ?
In meiner Anwendung gibt es mehrere Arten die Zuschauer, die teilen sich die selben Daten.(3D-voxel-Daten).Eg: der 2D-Viewer (XY-Ebene,YZ-Ebene,ZX-Ebene) und ein 3D-viewer.Und in Zukunft gibt es noch einige Zuschauer mehr. QWiget ist die Verwendung der Zeichnung und Darstellung von Daten. IView ist eine abstrakte Klasse/interface declare-Befehl Methoden und Daten für alle Arten von Zuschauern.
InformationsquelleAutor Ashika Umanga Umagiliya | 2010-06-11
Du musst angemeldet sein, um einen Kommentar abzugeben.
Haben Sie nicht zu erklären, init() in PlaneViewer, aber wenn Sie nicht PlaneViewer wird eine abstrakte Klasse, was bedeutet, dass Sie kann nicht instanziiert werden.
Wenn du meinst, wenn du Fragen hast zu haben 'void init ();" in die Headerdatei für PlaneViewer und in der .cpp-Datei. Die Antwort ist ja.
Ich denke, entweder Sie sind nicht das gleiche Gebäude-code oder Ihre Compiler-Befehl ist falsch.
Ich abgestreift das QT-Zeug und war in der Lage, bauen Sie Ihre code gerade fein mit g++.
Der Fehler bedeutet, dass die IViewer-Klasse nicht gefunden wurde, durch den linker.
Bekomme ich diesen Fehler wenn ich entfernen Sie das '=0' Teil, der macht 'IViewer::init()' eine rein virtuelle Funktion. Könnten Sie auch, dass Fehler, wenn Sie unkommentiert den Konstruktor und/oder Destruktor in der IViewer.
Nicht. C++ kümmert sich nicht, wenn es in einer .cpp-Datei, oder eine .h-Datei. Im Gegensatz zu Java, C/C++ - Präprozessor löst zuerst alle enthält und generiert eine Datei mit allen code. Anschließend übergibt Sie diese an C/C++ - compiler. Können Sie eigentlich gehören .cpp, wenn Sie wollen. Keine gute Idee, obwohl.
InformationsquelleAutor jcoffland
Eine gute Möglichkeit, um sich über interface-Klassen ist, dass Sie angeben, welche Methoden in abgeleiteten Klassen implementieren MÜSSEN.
Die schnelle Antwort ist, dass ja, müssen Sie implementieren die Methode init in
IViewer
da in der Basisklasse die Methode ist deklariert als rein virtuelle. Dies bedeutet, dass jede abgeleitete Klasse MUSS eine eigene implementation der Methode, da es keine Basisklasse implementierte Methode.Dies ist ein g++ - compiler-Fehler, der angibt (wie oben erwähnt), dass Sie eine abgeleitete Klasse von einer Basis, die eine rein virtuelle Funktion ist und dass die abgeleitete Klasse nicht implementieren Sie die rein virtuelle Methode wie es kommen muss.
Oh, und es sollte auch darauf hingewiesen werden, dass Sie nicht haben ein Problem mit Mehrfachvererbung, das problem würde weiterhin bestehen, wenn nur
IViewer
undPlaneViewer
beteiligt waren.InformationsquelleAutor radman
Ja, Sie haben zu erklären
init
in IhremPlaneViewer
als gut. Wenn nicht, danninit
nicht existieren würdenPlaneViewer
undPlaneViewer
würde immer noch als abstrakte (weil es keine Umsetzung derinit
).Müssen Sie definieren, leeren Körper für Ihre (virtuelle) Destruktor in
IViewer
. "Schnittstellen" in C++ nicht wirklich Schnittstellen, ist es nur durch Konvention, erstellen Sie eine Klasse mit rein virtuellen Methoden und keine Felder: aber Sie sind immer noch nur die "normalen" Klassen aus der compiler-Sicht, so dass Sie noch brauchen, um eine Implementierung der Destruktor.InformationsquelleAutor Dean Harding
Typinformation Problem wird verursacht, indem nicht die implementation eines destruktors für die IViewer-Klasse. In der Regel-Compiler generieren die interne Daten-Strukturen (zB. "typeinfo") zusammen mit der virtuellen Destruktor.
Müssen Sie kompilieren Sie und verknüpfen Sie eine Datei, die enthält:
Es ist gute Praxis, einen virtuellen Destruktor ist, denn dies gibt der compiler eine compilation unit zu verwenden, RTTI information, und es erlaubt auch dem operator delete, um korrekt zu arbeiten, wenn eine Basisklasse Zeiger.
Andere haben die Frage zu beantworten, die auf die init () - Methode, aber in Zusammenfassung: Wenn Sie gehen, um es zu implementieren in PlaneViewer, die Sie brauchen, es zu erklären.
InformationsquelleAutor janm
Ja, Sie brauchen, um neu zu erklären
virtual void init()
in der Unterklasse und umzusetzen, weilIViewer
erklärt die Funktion rein virtuelle.Sehen eine andere Frage für die Erklärung Ihrer Fehler. Sie wird verursacht durch die Deklaration einer virtuellen Funktion (nicht rein) und nicht, es zu definieren. Es ist nicht ersichtlich aus dem code, den Sie geschrieben, so dass ich vermute, Sie haben möglicherweise veraltete Objekt-Dateien, die wurden nicht wieder aufgebaut (Sie haben auskommentiert
IViewer
Konstruktor und virtual Destruktor).Als zusätzliche Anmerkung, sollten Sie eine virtuelle Destruktoren mit leeren Körper für Ihre Schnittstellen.
InformationsquelleAutor Alex B
Ich getan habe erhebliche Arbeit in beiden Sprachen und es ist ein cookie-cutter-pattern können Sie in der Regel Folgen, um wiederum eine Java-Schnittstelle in eine c++ - Schnittstelle:
//Start mit dem Java-Schnittstelle
C++ vor Java und nicht stören, Sie definieren das spezielle "Schnittstelle" Schlüsselwort für rein virtuelle Klassen. Damit Sie effektiv haben, um einige Arbeit zu tun, dass der Java-compiler automatisch:
//Der entsprechende C++ - Klasse
Eine weitere gute Regel zu Folgen, in C++ ist, wenn Sie Erben von einem Basis-Klasse mit rein virtuellen Methoden neu deklarieren Sie in der abgeleiteten Klasse, auch wenn Sie lassen Sie als pure virtuals. Es tut nicht weh, Leistung, und es lässt jeden wissen, dass das Objekt nur eine teilweise Umsetzung.
InformationsquelleAutor Zack Yezek