2017-01-15 5 views
1

Bearbeiten: Code aus Überschriften Datei hinzugefügt.Vererbung + Verwendung von Objekt (this) als Argument

Im Moment arbeite ich an einer Art von Simulation, und einige Probleme traten auf. Ich habe einige Klassen wie diese unter:

#ifndef CARTYLERIA_H 
#define CARTYLERIA_H 
#include "cjednostka.h" 
#include "cnieruchome.h" 
#include "battlewindow.h" 

class BattleWindow; 

class CArtyleria : public CJednostka, public CNieRuchome <------ error line 
{ 
public: 
    CArtyleria(); 
    void rysuj(BattleWindow *okno); 
}; 

#endif // CARTYLERIA_H 

Und wenn ich versuche, es zu kompilieren, ist ein Fehler in der markierten Linie:

erwartete Klassennamen vor „“ Token

Alles funktionierte ordnungsgemäß, bis ich den Zeiger zum BattleWindow-Objekt hinzufüge.

ist es gute Praxis CArtyleria Methode aufzurufen mit

diese

in BattleWindow Klassenobjekt?

Cjednostka.h:

#include "battlewindow.h" 

    class CJednostka 
    { 
    public: 
     CJednostka(); 
     virtual void rysuj (BattleWindow *okno) =0; 
} 

CNieRuchome.h:

class CNieRuchome 
{ 
public: 
    CNieRuchome(); 
protected: 
    int PozycjaX; 
    int PozycjaY; 
}; 

Und battlewindow.h:

#include <coddzial.h> 
#include "main.h" 
#include "ctimer.h" 
#include "cpotyczka.h" 
#include "cjednostka.h" 

namespace Ui { 
class BattleWindow; 
} 
class CPotyczka; 
class BattleWindow : public QMainWindow 
{ 
    Q_OBJECT 

public: 
    CPotyczka *potyczka; 
    void tworz_oddzial(); 
    explicit BattleWindow(QWidget *parent = 0); 
    ~BattleWindow(); 
    std::vector <QGraphicsPixmapItem*> items_vector; 
    void dodaj_jednostki(std::vector<QString> jednostki, QString frakcja); 
    void rysuj_jednostke(QString jednostka, QString frakcja, int x, int y); 

private slots: 

    void on_now(); 

private: 

    QGraphicsScene *scene; 
    Ui::BattleWindow *ui; 
    CTimer *timer; 


    void rysuj_jednostki(QString frakcja); 
    void rysuj_plansze(); 
    void rysuj_flagi(); 
    void usun_jednostke (QGraphicsPixmapItem *item); 
    std::list<CJednostka*> jednostki_do_narysowania; 
}; 

Und was ich tun möchte, ist:

Aufrufmethode für Objekte in S TL Liste std::list<CJednostka*> jednostki_do_narysowania;

Gerade jetzt ist es wie unten realisiert:

for(std::list <CJednostka*>::iterator it=jednostki_do_narysowania.begin();it!=jednostki_do_narysowania.end();++it){ 

     (*it)->rysuj(this); 
+3

Also haben Sie das Argument 'okno' hinzugefügt und dann haben Sie einen Fehler für die Zeile bekommen, die die Basisklassen definiert? Das klingt nicht richtig. Wie es aussieht, haben Sie nicht genug Code zur Verfügung gestellt. Wir wissen nicht, was in deinen drei '* .h' Dateien steht. –

+0

Eine häufige Ursache hierfür ist, dass eine der Include-Dateien wiederum diese Datei enthält (ein zirkuläres Include) und der Fehler auftritt, wenn die Datei ein zweites Mal mit dem bereits definierten Include-Guard gelesen wird. –

+0

Wenn Sie das Battlewindow weiterleiten, können Sie die Include-Anweisung löschen. das wird wahrscheinlich helfen. – Soeren

Antwort

0

ein paar Probleme mit diesem Code Es gibt keine.

Zuerst das Problem, das Sie kompilieren könnten, ist, weil Sie das Semikolon vermissen, wie Martin Broadhurst in seiner Antwort bemerkte.

Sie haben auch eine zirkuläre Abhängigkeit zwischen cjednostka.h und battlewindow.h.

Da cjednostka.h hat nur eine Schnittstelle Klasse entfernen die umfassen und eine Vorwärtsdeklaration für class BattleWindow hinzufügen, wie Sie in der cartyleria.h

tat

Nächstes Problem ist, dass Sie eine reine virtuelle Schnittstelle für CJednostka schaffen, aber es funktioniert nicht habe einen virtuellen Destruktor. Dies ist sehr schlecht und wird schließlich zu einer unkorrekten Zerstörung des Objekts durch den Basiszeiger führen.

Versuchen Sie dies in cjednostka.h

#ifndef CJEDNOSTKA_H 
#define CJEDNOSTKA_H 
class CJednostka 
{ 
public: 
    CJednostka(); 
    virtual ~CJednostka() = default; 
    virtual void rysuj (BattleWindow *okno) =0; 
}; 
#endif 

Auch entweder Kopfschutz in allen Header-Dateien oder #pragma once ich empfehlen. Bleiben Sie einfach bei einer Option und machen Sie dies in jeder Kopfzeile.

Ein weiteres Problem bei den Headern ist, dass in einem von ihnen können Sie Ihren eigenen Header als #include <coddzial.h> statt #include "coodzial.h" diese umfassen könnten zu einem Problem führen, da ein Unterschied in < gibt es> vs „“. Der erste durchsucht die Bibliothek Include Pfad der letztere sucht nach der Datei relativ zu Ihren Projektdateien und das ist sehr wahrscheinlich, was Sie wollen.

Schließlich ist ein Vorschlag in 90% der Szenarien Vektoren Listen überlegen und ich habe das starke Gefühl, dass Sie keine Liste benötigen. Ich empfehle, die Unterschiede zwischen den beiden noch einmal zu überprüfen.

+0

Jungs, ich versuche, angezeigte Probleme zu beheben, aber es gibt einige zusätzliche Probleme. Wenn ich eine Klassendeklaration in der Elternklasse hinzufüge: CJednostka ist es notwendig, es in vererbten Klassen wieder zu tun, haben sie Wissen und Zugang dazu? – BBq

+0

@BBq lesen Sie ein Buch oder ein Tutorial zu C++ - Klassen und Vererbung. Ich bin mir nicht sicher, was Sie unter "Klassen-Deklaration in Elternklasse hinzufügen" verstehen. –