invalid use of incomplete type Error bei Vererbung!
-
Hi!
Also meine grundlegende Überlegung ist es, eine Klasse GraphicObject zu haben, von welcher dann verschiedene Klassen (circle, rect....) abgeleitet werden.
Es soll eine Methode create() geben welche von den Unterklassen überschrieben wird und jeweil ein Objekt der Klasse erstellendie GraphicObject.h
class UserInterface; class GraphicObject { protected: UserInterface& userinterface_; public: GraphicObject(UserInterface& userinterface); virtual ~GraphicObject(); GraphicObject* create(); };GraphicObject.cpp
#include <iostream> #include "UserInterface.h" #include "GraphicObject.h" //------------------------------------------------------------------------------ GraphicObject::GraphicObject(UserInterface& userinterface): userinterface_(userinterface) { } //------------------------------------------------------------------------------ GraphicObject::~GraphicObject() { } GraphicObject* GraphicObject::create() { }und eine Abgeleitete Line.h
class UserInterface; class GraphicObject; class Line: public GraphicObject { private: int x1_; int x2_; int y1_; int y2_; int id_; int group_; UserInterface& userinterface_; public: Line* create(); Line(UserInterface& userinterface); Line(UserInterface& userinterface, int x1_, int x2_, int y1_, int y2_, int id_, int group_); virtual ~Line(); std::string readid(std::string& id); std::string readx1(std::string& x1); std::string ready1(std::string& y1); std::string readx2(std::string& x2); std::string ready2(std::string& y2); std::string readgroup(std::string& group); };Ich bekomme allerdings hier (wie bereits im Titel angedeutet) :
In file included from Line.cpp:16:0: Line.h:19:1: error: invalid use of incomplete type ‘struct GraphicObject’ Line.h:16:7: error: forward declaration of ‘struct GraphicObject’
Anhang:
Die konkreten GrafikObjekte brauchen alle eine create() Methode und mein Ziel ist es bei jener diese Objekte, z.B. line als GraphicObject* Objekt zu initialisieren, allerdings haben alle Objekte (z.B. line und circle) komplett andere Konstruktoren!
Ich danke schon im Vorhinein für eure Antworten!
mfg trunksen
-
Für Vererbung reicht die forward-declaration nicht, du musst die Klassendefinition vorher haben.
-> graphicobject.h einbinden.Allgemein:
Forward-decl reicht für:- Definition von Pointern und Referenzen
- Deklaration von Funktionsparametern und Rückgabetypen
Forward-decl reicht nicht für:
- Definition von Basisklassen
- Definition von Variablen und Membervariablen
- Zugriff auf Pointer und Referenzen
- Objekterzeugung/-zerstörung per new/delete
Schwierig wirds bei templates, wie z.B. smart-Pointern. Da können subtile Unterschiede auftreten.
-
Eine Forward declaration reicht hier nicht aus, du musst schon ...
ach Mist, pumuckl war schneller.
-
Vielen dank für die schnelle Antwort!
Ich hatte die GraphicObject in der Line.cpp inkludiert (sollte man ja im Header nicht machen oder?)
Line.cpp:
include <iostream> #include <string> #include <vector> #include "Line.h" #include "UserInterface.h" #include "GraphicObject.h" Line::Line(UserInterface& userinterface, int x1, int x2, int y1, int y2, int id, int group) : userinterface_(userinterface), x1_(x1), x2_(x2), y1_(y1), y2_(y2), id_(id), group_(group) { } Line::Line(UserInterface& userinterface): userinterface_(userinterface) { } Line::~Line() { } Line* Line::create() { std::string id; std::string x1; std::string x2; std::string y1; std::string y2; bool flag = false; std::string group; readid(id); readx1(x1); ready1(y1); readx2(x2); ready2(y2); readgroup(group); Line* line = new Line(userinterface_, ix1, ix2, iy1, iy2, iid, igroup); return line; . . . . }Inkludiere ich die GraphicObject im Header, schmeißt der compiler den Error beim Konstruktor v. Line da er versucht hier den Konstruktor von GraphicObject zu callen!
mfg trunksen
-
Du musst GraphicObject schon im Header von Line includieren.
Der Fehler ist ja auch klar. Es existiert kein trivialer Konstruktor von GraphicObject. Statt dessen einer der ein UserInterface als Parameter hat. Du musst also in der Initialisierungsliste von Line den Konstruktor von GraphicObject aufrufen.Line::Line(UserInterface& userinterface): GraphicObject(userinterface) { }Ähnlich dann auch für den anderen Konstruktor.
-
trunksen schrieb:
Ich hatte die GraphicObject in der Line.cpp inkludiert (sollte man ja im Header nicht machen oder?)
Wer sagt das? solange du keine zirkulären Abhängigkeiten reinbaust, ist es absolut üblich, daß sich Header gegenseitig einbinden.
-
Vielen dank!
Der Fehler tritt jetzt aber auch noch beim anderen Line Konstruktor auf (Line::Line(UserInterface&, int, int, int, int, int, int))!
Schreibe ich einen GraphicObject Ctor ohne UI funktioniert die Ableitung ohne Probleme, allerdings ist ja mein Ziel, dass ich irgendwann einmal die Zeile
GraphicObject* line = new Line(UserInterface&, int, int, int, int, int, int)oder gehört dann:
Line* line = new GraphicObject(UserInterface&, int, int, int, int, int, int)
Allerdings haben die abgeleiteten Klassen ja andere Ctor's
(z.B.: Circle(UserInterface&, int, int, int))Ich möchte das um dann einmal in etwa einen Vector der Form:
vector<GraphicObject*> govec;machen zu können in dem ich alle Objekte zur verfügung habe!
mfg trunksen
-
Merke: Wenn eine Basisklasse oder die Klasse eines Memberobjektes keine Default-Konstruktor hat, musst du in jedem Konstruktor der abgeleiteten/besitzenden Klasse in der Initialisierungsliste einen passenden Konstruktor für das Basisklassen/Member-Objekt aufrufen. Da führt kein Weg drum herum.
-
trunksen schrieb:
Der Fehler tritt jetzt aber auch noch beim anderen Line Konstruktor auf (Line::Line(UserInterface&, int, int, int, int, int, int))!
Ich hatte doch geschrieben, dass du auch da den Konstruktor von GraphicObject in der Initialisierungsliste mit aufrufen musst.
-
Ich hatte doch geschrieben, dass du auch da den Konstruktor von GraphicObject in der Initialisierungsliste mit aufrufen musst.
Sorry, dass habe ich wohl übersehen!
Merke: Wenn eine Basisklasse oder die Klasse eines Memberobjektes keine Default-Konstruktor hat, musst du in jedem Konstruktor der abgeleiteten/besitzenden Klasse in der Initialisierungsliste einen passenden Konstruktor für das Basisklassen/Member-Objekt aufrufen. Da führt kein Weg drum herum.
Ich habe jetzt den Ctor der Basisklasse als Default-Ctor definiert und jetzt funktioniert auch die Umwandlung!
Vielen vielen dank für eure Hilfe!!

mfg trunksen
-
trunksen schrieb:
Ich habe jetzt den Ctor der Basisklasse als Default-Ctor definiert und jetzt funktioniert auch die Umwandlung!
Moment, du hast eine Default-Ctor für GraphicObject? Und was ist mit der UserInterface-Referenz? Hast du die rausgenommen?
Falls dem so ist, hast du deinen Programmierfehler (=die fehlende Initialisierung im Line-Ctor) dadurch korrigiert, dass du dein komplettes Design geändert hast. Klingt irgendwie unglücklich, oder?
