Zwei Klassen sich gegenseitig speichern lassen?



  • Hallo zusammen,

    hab ein Problem welches ich gerne eleganter lösen würde als ich es bis jetzt tue. Ich habe die folgenden drei Klassen:

    // Action.h
    class Soldier;
    
    class Action
    {
    	public:
    		Action();
    
    		// Der hier sollte private sein
    		Soldier* attachedSoldier;
    };
    
    // Shoot.h
    #include "Action.h"
    
    class Shoot : public Action
    {
    
    	public:
    		Shoot(void) : Action(){};
    };
    
    // Soldier.h
    class Action;
    
    class Soldier
    {
    	private:
    		Action* attachedAction;
    
    	public:
    		Soldier();
    		void perform(Action* action);		
    };
    

    Das Ganze ist so: Der Programmierer soll verschiedene Aktionen (wie hier zB. Shoot) als eigene Klassen implementieren können, die er dann von der Klasse Action ableitet.

    Dann soll einem Soldaten per

    Soldier soldier;
    Shoot shoot;
    soldier.perform(&shoot)
    

    befohlen werden können diese Aktion auszuführen. Soweit so gut, das klappt auch alles.

    Jetzt will ich aber sowohl in dem Objekt des Soldaten die aktuelle Aktion speichern als auch in dem Objekt der Aktion den zugehörigen Soldaten. Ersteres ist einfach:

    // Soldier.cpp
    #include "Soldier.h"
    #include "Action.h"
    
    Soldier::Soldier(){}
    
    void Soldier::perform(Action* action)
    {
    	// Hier wird die aktuelle Aktion gespeichert
    	this->attachedAction = action;
    
    	// Hier wird der zur Funktion gehörende Soldat gespeichert
    	action->attachedSoldier = this;
    }
    

    Das alles funktioniert auch, aber nur weil das Feld attachedSoldier public ist. Ich würde dieses aber gerne private machen, da der Benutzer (= der Programmierer der die einzelnen Aktionen implementiert) darauf keinen Zugriff haben soll.

    Bis jetzt ist mir nur eingefallen die zwei Klassen per friend miteinander zu befreunden, allerdings will ich das auf keinen Fall so machen.

    Wie kann ich dieses Problem lösen?

    Viele Grüße,
    hs



  • Ich glaube, ich bin noch nicht wirklich kompetent genug um das Problem zu lösen, da ich erst jetzt mein erstes richtiges C++-Programm schreibe, aber neugierig macht mich dein Problem schon.

    Was macht denn der Compiler wenn du this nicht per Zuweisung an einen Member von Action übergibst, sondern als Parameter einer Methode von Action?



  • Der Kollege hier vor mir hat recht.

    Du kansnt dir ohne Probleme eine Methode schreiben:

    void Action::setAttachedSoldier(Soldier * s)
    {
        this->attachedSoldier = s;
    }
    
    void Soldier::perform(Action* action)
    {
        this->attachedAction = action;
        action->setAttachedSoldier(this);
    }
    

    Eventuell mal const in Erwägung ziehen.

    Auf einem anderen Blatt steht jedoch, ob das Klassendesign gut ist, in der Form.
    Das bezweifle ich nämlich. Die Kopplung zwischen Soldier und einer Action ist sehr stark. Und wieso soll sich die Action den Soldaten merken bzw umgekehrt, nachdem die Aktion ausgeführt ist.



  • Skym0sh0 schrieb:

    Der Kollege hier vor mir hat recht.

    Du kansnt dir ohne Probleme eine Methode schreiben:

    void Action::setAttachedSoldier(Soldier * s)
    {
        this->attachedSoldier = s;
    }
    

    Hallo,

    ich glaube hier liegt ein Missverständnis vor. Es geht hier gar nicht darum ob man jetzt eine Methode benutzt oder das Feld direkt anspricht. Dass ich das Feld mit einem Setter setzen kann ist mir schon klar.

    Mir geht es darum dass der Benutzer dieses Feld oder eben diese Methode gar nicht erst zur Verfügung haben soll. Die Methode setAttachedSoldier müsste ja auch wieder public sein damit ich sie benutzen kann. Und genau das will ich nicht.

    hs



  • Dann nimm friend. Dann merken andere auch direkt, dass am Design etwas nicht stimmt.



  • Nathan schrieb:

    Dann nimm friend. Dann merken andere auch direkt, dass am Design etwas nicht stimmt.

    Was soll das bringen? Ich suche nach einer Lösung die die Zugriffsrechte des Programmierers im Soldier scope weiter einschränkt, nicht erweitert. Mit einer friend Klasse werden alle private Member zugänglich das ist noch wesentlich schlechter als es jetzt ist.



  • warum igentlich so ein komisches klassendesign?

    soldier.shoot();//Bäm!
    

    //edit

    oder auch, wenn man halt komplizierten, langsamen Code mag:

    class Shoot
    {
        Soldier* mySoldier;
        public:
            Shoot(Soldier& soldier):mySoldier(soldier){}
            void aaaaandAction(){
                 mySoldier.perform(*this);
            }
    };
    
    Soldier soldier;
    
    Shoot shot(&soldier);
    shot.aaaaandAction();
    

Anmelden zum Antworten