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;
    };
    
    #endif
    

    ich 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.


Anmelden zum Antworten