problem mit vererbung...
-
ich habe ein kleines problem mit diesen klassen...
denn wenn ich mit:AbstractInfantry *ai = new AbstractInfantry; ai->setOwner(unit); Infantry *model1 = new Infantry(ai);ein objekt anlegen möchte, dann bekomme ich folgenden fehler:
error: cannot allocate an object of abstract type ‘Infantry’ ./army/Model.h:104: note: because the following virtual functions are pure within ‘Infantry’: ./army/Model.h:86: note: virtual double Model::angle() ./army/Model.h:87: note: virtual double Model::height() ./army/Model.h:88: note: virtual double Model::width() ./army/Model.h:89: note: virtual void Model::face(double) ./army/Model.h:90: note: virtual void Model::turn(double) ./army/Model.h:91: note: virtual void Model::sTurn(bool) ./army/Model.h:92: note: virtual bool Model::turning() battlefield/Board.cpp:32: warning: unused variable ‘model1’ battlefield/Board.cpp: At global scope: battlefield/Board.cpp:85: warning: unused parameter ‘event’ make[1]: *** [release/Board.o] Fehler 1#ifndef MODEL_H #define MODEL_H #include <QPointF> #include <QPixmap> enum EModelType { MT_INFANTRY, MT_VEHICLE, MT_WALKER }; class Unit; /* Abstrakte Modell-Klasse mit generellen Eigenschaften ohne aktuelle BF-Daten */ class AbstractModel { public: //hat in abstr. klassen nix zu suchen // AbstractModel(); void setOwner(Unit *owner) {own_un = owner;}; void setOwner(int owner) {own_id = owner;}; int inline owner_id() {return own_id;}; // Unit-ID der Einheit der das Modell angehoert Unit inline *owner() {return own_un;}; // Zeiger auf Einheit der das Modell angehoert private: Unit* own_un; int own_id; }; /* Alles was kein Fahrzeug ist */ class AbstractInfantry : public AbstractModel { public: double inline size() {return base_diam;}; // Base-Durchmesser private: double base_diam; }; /* Laeufer */ class AbstractWalker : public AbstractModel { public: double inline size() {return base_diam;}; // Base-Durchmesser private: double base_diam; }; /* Fahrzeuge */ class AbstractVehicle : public AbstractModel { public: double inline height() {return h;}; // Ausmasse. Vereinfachend wird angenommen dass Fahrzeuge Rechtecksgrundform haben. double inline width() {return w;}; private: double h; double w; }; /* zusaetzliche Eigenschaften+Routinen fuer auf dem Schlachtfeld befindliche Modelle */ class Model { public: // Model(Unit* owner); Model(AbstractModel* base); // Konstruktor aus bestehendem AbstractModel ~Model(); void inline select(bool s) {sel = s;}; bool inline selected() {return sel;}; // ist das Modell gerade selektiert? void inline sMove(bool m) {mov = m;}; bool inline moving() {return mov;}; // wird das Modell gerade bewegt? int inline owner_id() {return m->owner_id();} ; // Unit-ID der Einheit der das Modell angehoert QPointF inline position() {return pos;}; // Position des Modells auf dem Schlachtfeld, in Zollkoordinaten Unit inline *owner() {return m->owner();}; // Zeiger auf Einheit der das Modell angehoert void inline move(double x, double y) {pos.setX(pos.x() + x); pos.setY(pos.y() + y);}; // relative Bewegung void inline set_position(double x, double y) {pos.setX(pos.x() + x); pos.setY(pos.y() + y);}; // absolute Positionsaenderung virtual EModelType type() = 0; virtual double size() = 0; virtual double angle()= 0; virtual double height() = 0; virtual double width() = 0; virtual void face(double a) = 0; virtual void turn(double a) = 0; virtual void sTurn(bool t) = 0; virtual bool turning() = 0; private: QPointF pos; bool sel; bool mov; AbstractModel* m; }; /* zusaetzliche Eigenschaften fuer auf dem Schlachtfeld befindliche Laeufer */ class Infantry : public Model { public: Infantry(Model*); double inline size() {return m->size();}; EModelType inline type() { return MT_INFANTRY; }; private: AbstractInfantry* m; }; /* zusaetzliche Eigenschaften fuer auf dem Schlachtfeld befindliche Laeufer */ class Walker : public Model { public: Walker(Model*); double inline angle() {return ang;}; // Ausrichtungswinkel relativ zur x-Achse. double inline size() {return m->size();}; void inline face(double a) {ang = a;}; void inline turn(double a) {ang += a;}; EModelType inline type() { return MT_WALKER; }; private: double ang; AbstractWalker* m; }; /* zusaetzliche Eigenschaften fuer auf dem Schlachtfeld befindliche Fahrzeuge */ class Vehicle : public Model { public: Vehicle(Model*); void inline sTurn(bool t) {tur = t;}; bool inline turning() {return tur;}; // wird das Modell gerade gedreht? double inline angle() {return ang;}; // Ausrichtungswinkel relativ zur x-Achse. double inline height() {return m->height();}; double inline width() {return m->width();}; void inline face(double a) {ang = a;}; void inline turn(double a) {ang += a;}; EModelType inline type() { return MT_VEHICLE; }; private: double ang; bool tur; AbstractVehicle* m; }; #endifich weiß nicht ganz warum...
-
Infantry *model1 = new Infantry(ai);Du kannst kein Objekt einer Klasse erstellen, die nicht _alle_ geerbten, rein virtuellen methoden überschreibt. Steht doch wunderbar in der Fehölermeldung.
virtual EModelType type() = 0; virtual double size() = 0; virtual double angle()= 0; virtual double height() = 0; virtual double width() = 0; virtual void face(double a) = 0; virtual void turn(double a) = 0; virtual void sTurn(bool t) = 0; virtual bool turning() = 0;
-
Du willst eine Instanz von Infantry erzeugen.
Dies kann jedoch nicht funktionieren da Infantry eine Abstrakte Klasse ist und du keine abstrakten Klassen instanzieren kannst.
Eine Klasse ist dann abstrakt wenn sie eine oder mehrere pur virtuelle Funktionen hat.
In deinem Beispiel ist Infantry abgeleitet von Model und Model sieht folgendermassen aus:/* zusaetzliche Eigenschaften+Routinen fuer auf dem Schlachtfeld befindliche Modelle */ class Model { public: // Model(Unit* owner); Model(AbstractModel* base); // Konstruktor aus bestehendem AbstractModel ~Model(); void inline select(bool s) {sel = s;}; bool inline selected() {return sel;}; // ist das Modell gerade selektiert? void inline sMove(bool m) {mov = m;}; bool inline moving() {return mov;}; // wird das Modell gerade bewegt? int inline owner_id() {return m->owner_id();} ; // Unit-ID der Einheit der das Modell angehoert QPointF inline position() {return pos;}; // Position des Modells auf dem Schlachtfeld, in Zollkoordinaten Unit inline *owner() {return m->owner();}; // Zeiger auf Einheit der das Modell angehoert void inline move(double x, double y) {pos.setX(pos.x() + x); pos.setY(pos.y() + y);}; // relative Bewegung void inline set_position(double x, double y) {pos.setX(pos.x() + x); pos.setY(pos.y() + y);}; // absolute Positionsaenderung virtual EModelType type() = 0; virtual double size() = 0; virtual double angle()= 0; virtual double height() = 0; virtual double width() = 0; virtual void face(double a) = 0; virtual void turn(double a) = 0; virtual void sTurn(bool t) = 0; virtual bool turning() = 0; private: QPointF pos; bool sel; bool mov; AbstractModel* m; };Also die Methoden type(), size(), angle(), height(), width(), face(double a), turn(double a), sTurn(bool t) und turning() sind alle pure virtual.
Das heisst weiter wenn du von dieser Klasse ableiten willst und diese abgeleitete Klasse dann instanzieren willst musst du all diese pure virtual Functions ueberladen damit die davon abgeleitete Klasse (Infantry in deinem Fall) nicht abstrakt ist und du sie instanzieren kannst.
Wenn du sie nicht ueberladest, dann erbst du sie als pure virtual. Dies macht deine abgeleitete Klasse dann abstrakt.In der Klasse Infantry wird aber keine der pure virtual Functions ueberladen, deshalb bleibt Infantry auch abstrakt und ist somit nicht instanzierbar.