Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Klassen-Hierarchie

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
01.04.2005, 16:37 Uhr
Th



Hi, ihr Gurus.

Ich habe eine Basisklasse, von der viele Klassen abgeleitet sind. Nun möchte ich den Klassen zusätzliche Funktionalität geben. Jedoch sind diese Klassen nicht von mir geschrieben, sondern aufgrund der Projekthierarchie kann und will ich diese Klassen nicht verändern.


C++:
// Basisklasse
class CBaseSpaceObject
{

};

// abgeleitete Klassen

class CHunter : public CBaseSpaceObject
{
}

class CPlanet : public CBaseSpaceObject
{
}

// ... und noch ca 20 weitere




Diese Klassen sind zwar mit einem enum versehen (SPACE_HUNTER, SPACE_PLANET, ...) und bisher habe ich meistens ein Array angelegt, um z.B. die (lokalisierten) Namen dieser Objekte aus der StringRessource zu lesen, also

C++:
const char *cID[CBaseSpaceObject::SPACE_MAX_OBJECTS] =
{
  "ID_SPACEOBJ_HUNTER",
  "ID_SPACEOBJ_PLANET",
  ...
}


Jedoch wenn sich die enums ändern, gibt es Chaos und ich muß diese Daten immer von Hand aktualisieren.

Mir wäre es jedoch lieber, es gäbe hierfür einen objektorientierten Ansatz. Ich hatte schon an eine Factory-Klasse gedacht, welche für jede Klasse eine neue Klasse generiert, in der ich dann die neuen Funktionalitäten hinzufüge.

Welchen Ansatz haltet ihr für geeignetesten?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
01.04.2005, 19:59 Uhr
ao

(Operator)


Du willst den Klassen neue Funktionalität geben, aber sie nicht verändern? Ich verstehe nicht, was du vorhast.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
02.04.2005, 07:51 Uhr
(un)wissender
Niveauwart


Das Problem habe ich auch...
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
04.04.2005, 10:28 Uhr
Th



Hey, sorry, daß ich nicht verstanden werde -)

Wir arbeiten an einem (komplexen) Programm (Spiel), so daß jeder Entwickler seinen eigenen Bereich hat. Nun existieren diese besagten 20 Klassen und aufgrund der Projekthiererchie haben diese z.B. keinen Zugriff auf die String-Ressourcen oder andere Interface-Funktionen. Jedoch benötigt umgekehrt das Interface (an dem ich arbeite) Infos bzgl. dieser BaseSpaceObjects, welche bisher über die enums realisiert werden.
Jedoch gefällt mir dieser Ansatz nicht so toll.

Nun mein Ansatz:
Ich will von jeder der abgeleiteten Klassen jeweils eigene Klassen entwerfen, welche von diesen abgeleitet sind, also z.B.

C++:
class Interface
{
public:
   std::string Name() const = 0;
};

class CMyHunter : public Hunter, public Interface
{
public:
    std::string Name() const;
};



Mein Problem:
Wenn ich jetzt diese ca. 20 neuen Klassen generiert habe (habe hierfür einen Source-Code Generator, den ich selbst geschrieben habe), und dann eine Referenz oder Zeiger auf eine BaseSpaceObjekt erhalte, so muß ich daraus dann eine konkrete Referenz oder Zeiger auf meine abgeleiteten Klassen erzeugen. Hierfür würde ich dann wohl eine Factory-Klasse benötigen.

Ich frage mich nur, ob dies noch etwas einfacher geht (ohne die Basisklassen zu verändern aber trotzdem einigermaßen objektorientiert)???
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
04.04.2005, 12:37 Uhr
Spacelord
Hoffnungsloser Fall


Hallo,
such mal bei google nach dem Dekorierer Pattern.
Ich denke das sollte dir eigentlich weiterhelfen.

MfG Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
05.04.2005, 10:45 Uhr
Th



Hab mir mal das Dekorier-Pattern (Wrapper) angesehen. Leider kann ich es so nicht gebrauchen, da ich ja Funktionalitäten in Abhängigkeit der abgeleiteten Klassen hinzufügen will (keine generellen Eigenschaften, wie in den Beispielen z.B. Textbox mit Rahmen versehen).

Eine andere Funktionalität wurde jetzt doch bei uns in die Basisklasse integriert, nämlich ob ein SpaceObject als Target anwählbar ist. Somit hab ich jetzt vorerst nur noch den anzeigbaren Namen zu verwalten.

Also bleibt es erstmal so wie es ist...
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
05.04.2005, 19:44 Uhr
Spacelord
Hoffnungsloser Fall


Also offensichtlich kapiere ich immer noch nicht wo genau dein Problem liegt.....
Insbesondere frage ich mich warum nicht einfach ne Schnittstellenmethode hinzugefügt wird mit der du auf die Namen zugreifen kannst?
Kann doch nicht sein dass du zig Klassen ableiteten musst um an diese Information zu kommen!?
Die Methode Name aus deinem Interface wird doch wohl nichts anderes machen als den jeweiligen String aus einer der konkreten Subklassen von BaseSpaceObject zurück zu geben,oder?
Das lässt sich doch durchaus mit ner Dekoriererklasse lösen.Dank Polymorphie bekommst du da doch auch den String der konkreten Unterklasse

Also so wie ich dich bislang verstanden habe wäre dass hier ne vertretbare Lösung(trotz der friend Deklaration in der Basisklasse).Obwohl dadurch die Kapselung etwas unterhölt wird finde ich die Lösung trotzdem gelungener als 20 SubSubklassen abzuleiten.
Das ganze ist in absoluter Minimalform und ohne jegliche Fehlerprüfung.


C++:
#include <iostream>
#include <string>

using namespace std;

class BaseSpaceObject
{
public:
    virtual void foo1() = 0;
    virtual void foo2() = 0;
protected:
    string name;

    friend class BaseSpaceObject_Deko;
};

class Hunter:public BaseSpaceObject
{
public:
    Hunter(){name="Ich bin ein Hunter!";}
    virtual void foo1(){cout<<"Hunter::foo1\n";}
    virtual void foo2(){cout<<"Hunter::foo2\n";}
};

class Planet:public BaseSpaceObject
{
public:
    Planet(){name="Ich bin ein Planet!";}
    virtual void foo1(){cout<<"Planet::foo1\n";}
    virtual void foo2(){cout<<"Planet::foo2\n";}
};

class BaseSpaceObject_Deko:public BaseSpaceObject
{
protected:
    BaseSpaceObject* ziel;
public:
    BaseSpaceObject_Deko(BaseSpaceObject* a):ziel(a){}
    virtual ~BaseSpaceObject_Deko(){delete ziel;}
    virtual void foo1(){ziel->foo1();}
    virtual void foo2(){ziel->foo2();}
    string getName()const{return ziel->name;}
};


int main()
{
    int i;
    BaseSpaceObject_Deko* bsod[3];
    bsod[0]= new BaseSpaceObject_Deko(new Hunter());
    bsod[1]= new BaseSpaceObject_Deko(new Planet());
    bsod[2]= new BaseSpaceObject_Deko(new Hunter());
    for(i=0;i<3;i++)
    {
        bsod[i]->foo1();
        cout<<(bsod[i]->getName())<<endl;
    }
    
    
    for(i=0;i<3;i++)
    {
        delete bsod[i];
    }

    return 0;
}




Die Ausgabe ist:
Hunter::foo1
Ich bin ein Hunter!
Planet::foo1
Ich bin ein Planet!
Hunter::foo1
Ich bin ein Hunter!

Die Objekte vom Typ BaseSpaceObject_Deko unterstützen die komplette Schnittstelle von BaseSpaceObject und können somit an jeden Klienten der nen Objekt dieses Typs erwartet übergeben werden.

Anscheinend möchtest du aber ja was anderes machen.Dann haben wir hiermit aber wenigstens ne Grundlage um zu klären was bei dir anders ist,oder was du anders machen möchtest!?

MfG Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
06.04.2005, 07:58 Uhr
(un)wissender
Niveauwart


BaseSpaceObject braucht einen virtuellen Destruktor.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
06.04.2005, 20:44 Uhr
Spacelord
Hoffnungsloser Fall



Zitat von (un)wissender:
BaseSpaceObject braucht einen virtuellen Destruktor.


Yep,der fehlt... .
Anscheinend ist das Thema für Th aber ja ohnehin durch.
Schade eigentlich,irgendwelche Designprobleme finde ich eigentlich immer recht interessant.

MfG Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
07.04.2005, 10:46 Uhr
Th



Nein, das Problem ist, daß die Basisklasse, sowie die davon abgeleiteten Klassen keinen Zugriff auf die StringRessourcen haben. Es geht darum, daß ich einen lokalisierbaren Namen im Interface für jedes SpaceObjekt anzeigen will - eben in Abhängigkeit des jeweiligen Typs.
Also so daß im Deutschen dann z.B. "Jäger" angezeigt wird und in der englischen Version "Hunter" und im chinesichen wiederum komische kryptische Zeichen... -)

Also geht die oben beschrieben Methode nicht - wäre ja auch zu einfach.
Ich bin schließlich (professioneller) Software-Entwickler und suche immer wieder neue gute portierbare Methoden. Na ja, Anfang nächsten Jahres könnt ihr dann das Spiel erwerben...
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: