Container mit Objekten verschiedener Klassen



  • siroeduardo schrieb:

    Jeder Character hat verschiedene Gegenstände bei sich. Diese sind z.B. im Rucksack, in Hosentaschen, am Kopf, .... abgelegt.
    Jetzt war die Idee einen Vector oder Array zu machen, welches die genauen Positionen für die Gegenstände repräsentiert.
    Die angelegten Gegenstände können selbst wieder Container sein.
    In den Containern kann auch wieder alles liegen.

    Das klingt genau so als wuerden alle Gegenstaende etwas gemeinsam haben. Das schreit ja foermlich danach von einer Basisklasse zu erben.

    Ich könnte natürlich eine Monsterklasse machen, welche so flexibel ist, alles zu verwalten.
    Aber das wäre eine reine Verschwendung, da viele Membervariablen immer leer wären.
    Damit hätte ich natürlich absolut kein Problem die Dinge in einem Vector zu verstauen.

    Schau dir mal Vererbung an.



  • siroeduardo schrieb:

    Jetzt war die Idee einen Vector oder Array zu machen, welches die genauen Positionen für die Gegenstände repräsentiert.

    Nur Nebenbei: Hier würde sich wohl eine map anbieten (key->Gegenstand, value->Position)

    siroeduardo schrieb:

    Jeder Gegenstand, hat abhängig von seinem Zweck verschiedenste Eigenschaften und kann auch diverse Eigenschaften des Characters ändern.
    Manche Dinge sind real andere fantasy.

    Klingt doch schonmal nach ner Schnittstelle (UsableElement)

    void useFor(Character& character);
    

    In der Methode setzt du dann die entsprechenden Änderungen in deinem Character

    So kannst du auf allen Elementen im Vektor

    useFor(me); // oder wie auch immer
    

    aufrufen.

    Wenn du lieber alle Elemente in deinem Charakter verwalten möchtest,
    delegierst du

    character.consume(*this);
    

    Der Parameter kann dann genau den richtigen Typ verwenden...

    Dann brauchste aber mehrere consume-Funktionen mit allen Element-Typen als Parameter.

    Soweit meine Idee...

    Gruß,
    CSpille



  • CSpille schrieb:

    siroeduardo schrieb:

    Jetzt war die Idee einen Vector oder Array zu machen, welches die genauen Positionen für die Gegenstände repräsentiert.

    Nur Nebenbei: Hier würde sich wohl eine map anbieten (key->Gegenstand, value->Position)

    Wäre es nicht eigentlich sinnvoller zu sagen: CharacterEquipment[Position] = Gegenstand ?

    bzw.

    Inventory[Position] = Gegenstand;

    Also genau umgekehrt zu deiner Definition, halte ich in diesem Fall für sinnvoller, da übersichtlicher...

    MFG
    Blackskyliner



  • Blackskyliner schrieb:

    CSpille schrieb:

    siroeduardo schrieb:

    Jetzt war die Idee einen Vector oder Array zu machen, welches die genauen Positionen für die Gegenstände repräsentiert.

    Nur Nebenbei: Hier würde sich wohl eine map anbieten (key->Gegenstand, value->Position)

    Wäre es nicht eigentlich sinnvoller zu sagen: CharacterEquipment[Position] = Gegenstand ?

    bzw.

    Inventory[Position] = Gegenstand;

    Also genau umgekehrt zu deiner Definition, halte ich in diesem Fall für sinnvoller, da übersichtlicher...

    MFG
    Blackskyliner

    Ich hab auch erst überlegt, ob evtl. anders rum.
    Möchte ich dir nicht widersprechen...
    Kommt drauf an in welchem Kontext er es verwendet.
    Aber je länger ich drüber nachdenke, gebe ich dir eher recht als
    dass ich meinen ursprünglichen Vorschlag verteidigen möchte.



  • Ihr müsst das von der praktischen Seite betrachten. Wenn der Gegendstand als Key fungiert, dann kann dieser Gegenstand sich nicht mehrmals im Inventar befinden. Dieses Problem wäre behoben, wenn die Position als Key fungiert, da sie eindeutig ist.

    Das ließe sich zwar auch mit einer Multimap realisieren, aber das erachte ich als den falschen Weg, da man es sich dadurch unnötig umständlich macht.

    Fazit: Key: Position, Value: Gegenstand.



  • Ist beides nicht unbedingt der Weisheit letzter Schluss. Wenn Position sowas wie Rucksack, Kopf usw. ist, können sich nicht mehrere Gegenstände im Rucksack befinden.
    Eine andere Möglichkeit wäre, dass sich an der Position Rücken ein Container-Gegenstand vom Typ Rucksack befindet. Wäre eventuell eine sinnvolle Möglichkeit, mehrere Rucksäcke hat man ja genausowenig wie mehrere Mützen.



  • ..... schrieb:

    Ihr müsst das von der praktischen Seite betrachten. Wenn der Gegendstand als Key fungiert, dann kann dieser Gegenstand sich nicht mehrmals im Inventar befinden. Dieses Problem wäre behoben, wenn die Position als Key fungiert, da sie eindeutig ist.

    Versteh ich nicht...
    Reden wir von einem Gegenstand oder einem Gegenstands-Typ?
    Es können doch mehrere Gegenstände des gleichen Typ existieren und sie müssen
    noch lange nicht gleich sein...

    Wenn du allerdings die Postion als Key vorschlägst, muss ich dir sagen,
    dass ich Taschenmesser und Kondome in der Hosentasche habe 🤡

    Dabei kriegst du Probleme mit dem Mapping der Position.
    Solange allerdings jeder Ort nur einen Gegenstand hat, ist alles knorke...

    EDIT: @ipsec: Ich war nur zu langsam, aber dafür kreativer mit dem Beispiel :p



  • CSpille schrieb:

    A* a = dynamic_cast<A*>(myVar);
    

    machen.
    Dieser liefert (bei Zeigern) NULL zurück, wenn es nicht von dem Typ ist

    Wird keine Exception geworfen vom Typ bad_cast?



  • aber aber ich dachte schrieb:

    CSpille schrieb:

    A* a = dynamic_cast<A*>(myVar);
    

    machen.
    Dieser liefert (bei Zeigern) NULL zurück, wenn es nicht von dem Typ ist

    Wird keine Exception geworfen vom Typ bad_cast?

    afaik bei Referenze...

    deswegen hab ich ja "(bei Zeigern)" dazu geschrieben



  • ipsec schrieb:

    Eine andere Möglichkeit wäre, dass sich an der Position Rücken ein Container-Gegenstand vom Typ Rucksack befindet. Wäre eventuell eine sinnvolle Möglichkeit, mehrere Rucksäcke hat man ja genausowenig wie mehrere Mützen.

    Das scheint mir eine sinnvolle Lösung zu sein.
    Ein Gegenstand pro Platz sollte reichen, denn notfalls kann man auch weitere einrichten (z.B. zwei Ring-Slots).

    Wenn der Rucksack nicht austauschbar sein soll bzw. selbst kein Gegenstand ist, kann er auch direkt zum Charakter gehören.
    Die Hosentaschen können entweder Teil der Hose sein oder auch direkt zum Charakter gehören. Die Frage dabei ist, ob du willst, dass deine Gegenstände in der alten Hose bleiben (können), wenn du eine neue anziehst.



  • aber aber ich dachte schrieb:

    CSpille schrieb:

    A* a = dynamic_cast<A*>(myVar);
    

    machen.
    Dieser liefert (bei Zeigern) NULL zurück, wenn es nicht von dem Typ ist

    Wird keine Exception geworfen vom Typ bad_cast?

    Als kurzes Beispiel:

    #include <iostream>
    
    class A{
    public: virtual ~A(){}
    };
    class B : public A{};
    class C : public A{};
    
    int main(){
            B b;
            A* a = &b;
            C* c = dynamic_cast<C*>(a);
            if(c==NULL)
                    std::cout << "ups..." << std::endl;
            A& a2(b);
            try{
                    C& c2(dynamic_cast<C&>(a2));
            }
            catch(std::bad_cast& e){
                    std::cout << "ups..." << std::endl;
            }
    }
    

    ups...
    ups...



  • ah danke 👍



  • CSpille schrieb:

    ..... schrieb:

    Ihr müsst das von der praktischen Seite betrachten. Wenn der Gegendstand als Key fungiert, dann kann dieser Gegenstand sich nicht mehrmals im Inventar befinden. Dieses Problem wäre behoben, wenn die Position als Key fungiert, da sie eindeutig ist.

    Versteh ich nicht...
    Reden wir von einem Gegenstand oder einem Gegenstands-Typ?
    Es können doch mehrere Gegenstände des gleichen Typ existieren und sie müssen
    noch lange nicht gleich sein...

    Wenn du allerdings die Postion als Key vorschlägst, muss ich dir sagen,
    dass ich Taschenmesser und Kondome in der Hosentasche habe 🤡

    Dabei kriegst du Probleme mit dem Mapping der Position.
    Solange allerdings jeder Ort nur einen Gegenstand hat, ist alles knorke...

    EDIT: @ipsec: Ich war nur zu langsam, aber dafür kreativer mit dem Beispiel :p

    Ich war davon ausgegangen, dass jeder Ort nur einen Gegenstand beinhalten kann. Aber selbst wenn das nicht der Fall ist, kann ein zusätzlicher Container auch dies richten.

    In jedem Fall ist die Position als Key der richtige Weg. Schließlich will man bei einem Nahkampangriff wissen, welche Waffen in den Händen sind. Bei Gegenstand -> Position wäre das nur sehr ineffizient zu lösen.



  • ,,,,, schrieb:

    In jedem Fall ist die Position als Key der richtige Weg. Schließlich will man bei einem Nahkampangriff wissen, welche Waffen in den Händen sind. Bei Gegenstand -> Position wäre das nur sehr ineffizient zu lösen.

    Stimmt...
    Ich benutze auch nur die Waffe, die ich gerade in den Händen halte... 😕
    Vielleicht möchte ich ja meinen Zauberstab rausholen, je nachdem, wer gerade vor
    mir steht.

    Nein... Nicht der Zauberstab für den ich die Kondome benötige 😃

    EDIT: Ich denke beide Richtungen können hilfreich sein. Also evtl. etwas bidirektionales.
    Meine eigentliche Intention war es, siroeduardo zu sagen, dass es wohl eine
    bessere Wahl als den Vektor gibt. Ich halte mich dann mal aus der langwierigen Diskussion, falls sie weitergeht, raus.



  • Besten Dank für euer Antworten.

    Ich nehme mal folgendes mit:

    1.) static_cast oder dynamic_cast lässt sich definitiv nicht vermeiden
    Das hatte ich erhofft, ist mir aber auch so recht 😉

    2.) Container
    Hier dachte ich zu erst an Vectoren, wegen den schnellen Zugriff []
    Map hat aber doch einige Vorteile, daher werde ich so wohl verwenden.
    Da Gegenstände aber ein Volumen besitzen ist Map wohl besser geeignet

    Genau so ist es:
    Üblicherweise wird nur das verwendet was in den Händen, Füssen oder im Kopf (Zauberspruch) "angelegt" ist. Alles andere muss zuerst angelegt werden.
    Komme ich aus dem Fernkampf wechsle ich vom Bogen zu Nahkampfwaffen.
    Und hier war der Gedanke die Positionen im Vector zu speichern.
    [0] rechte Hand
    [1] linke Hand
    .....

    Mit besten Dank
    Eduard



  • siroeduardo schrieb:

    1.) static_cast oder dynamic_cast lässt sich definitiv nicht vermeiden
    Das hatte ich erhofft, ist mir aber auch so recht

    CSpille schrieb:

    siroeduardo schrieb:

    Jeder Gegenstand, hat abhängig von seinem Zweck verschiedenste Eigenschaften und kann auch diverse Eigenschaften des Characters ändern.
    Manche Dinge sind real andere fantasy.

    Klingt doch schonmal nach ner Schnittstelle (UsableElement)

    void useFor(Character& character);
    

    In der Methode setzt du dann die entsprechenden Änderungen in deinem Character

    So kannst du auf allen Elementen im Vektor

    useFor(me); // oder wie auch immer
    

    aufrufen.

    Wenn du lieber alle Elemente in deinem Charakter verwalten möchtest,
    delegierst du

    character.consume(*this);
    

    Der Parameter kann dann genau den richtigen Typ verwenden...

    Dann brauchste aber mehrere consume-Funktionen mit allen Element-Typen als Parameter.

    Soweit meine Idee...


Anmelden zum Antworten