zu bentzenden klassennamen an funktion weitergeben ?



  • hi,
    eigentlich sollte das einfach sein:

    innerhalb einer funtion soll auf eine klasse zugegriffen werden ,z.b:
    DiesesObjekt.SollGezeichnetWerden(3,2);
    ich weiß aber nicht welche objekte alles gezeichnet werden müssen...wahrscheinlich werde ich eine dynamische liste anlegen , die dann ständig abgefragt wird.
    z.b.als char-array.
    ich hab es schon mit zeiger probiert also z.b

    ZEIGERAUFCHARARRAY.SollGezeichnetWerden(3,2);

    kriege dann aber immer : ..request for member...wich is of non-agregate type char..

    fällt dazu jemandem was ein ?
    thx.



  • So wie du das willst, geht es nicht. Das würde eine Compilierung während der Laufzeit erfordern.

    Wenn du unbedingt anhand eines Strings/Char-Arrays ein Objekt auswählen willst, wirst du um ein switch o.ä. nicht rumkommen.

    Ansonsten beschreib dein Problem etwas konkreter. Scheint mir so, als wäre da eine Basisklasse angebracht, damit du in einer list einen gemeinsamen Nenner hast.



  • Das was du meinst ist wahrscheinlich Reflection und bedeutet die Benutzung einer Klasse anhand ihres Namens als String. Das ist eine Sache die in Java super klappt aber in C++ leider gar nicht und wenn überhaupt nur sehr schwer geht. Ich habe da noch keine befriedigende Lösung gefunden.
    Unter Windows habe ich einen kleinen Workaround der allerdings nicht gerade elegant ist und darauf hinausläuft jede Klasse in eine DLL zu packen. Wie gesagt, nicht schön aber geht. Wenn es interessiert kann ich das gern noch näher erläutern

    Achja und wenn jemand wissen sollte wie man Reflection unter C++ hinbekommt wär es schön, dass hier mitzuteilen.



  • Drakos schrieb:

    Achja und wenn jemand wissen sollte wie man Reflection unter C++ hinbekommt wär es schön, dass hier mitzuteilen.

    ka, ob es was damit zu tun hat (kenn mich damit selber nicht so aus), aber hat typeid was damit zu tun?



  • Wenn alle Klassen eine gemeinsame Basisklasse haben könnte das stichwort:

    virtuelle Methode

    was für Dich sein:

    struct Base
    {
      void Zeichnen(int,int) = 0;
    }
    
    struct Kreis : public Base
    {
      void Zeichnen(int,int)
     {
     }
    }
    
    struct Linie : public Base
    {
      void Zeichnen(int,int)
     {
     }
    }
    
    void Zeichne(Base * b)
    {
      b->Zeichnen;
    }
    
    Linie l;
    Kreis k;
    
    Zeichne(&l); // Zeichnit Linie
    Zeichne(&k) // Zeichnet Kreis
    


  • Wie die anderen bereits sagten, das was du willst, funktioniert so nicht. Und wenn ich es richtig sehe, hilft dir hier ganz einfach Polymorphie weiter und dein Problem wird schon tausendfach in anderen OO-Programmen genutzt.

    Was willst du zeichnen? Eigentlich nur Objekte die auch gezeichnet werden können. Objekte die nicht gezeichnet werden können, werden auch niemals dafür in Frage kommen. DAfür sind zwei Dinge nötig:

    1. eine Basis-Klasse die als "zeichenbar" gilt.
    2. diese Klasse muß eine virtuelle Methode "zeichne()" haben.

    Du kannst dafür auch Mehrfachvererbung venutzen, was aber ziemlich komplex und fehleranfällig für einen OO-Anfänger sein kann.

    Leite also alle deine Klassen die gezeichnet werden sollen können mit der oben genannten Lösung ab.

    Dann nimm einen std::vector oder ein anderes Array und lege darin alle deine Objekte mit new darin ab. Wenn du das Array durchgehst, kann es dir egal sein ob das objekt gezeichnet wird, da jedes Objekt selbst entscheidet ob es gezeichnet wird.

    Objekte die nichts tun sollen, bekommen einfach eine leere zechne()-Methode und fertig. Sinnvollerweise ist die Basis-Methode einfach leer... fertig. Kein typeid oder Laufzeit-Informationen nötig... benötigt unnötige Resourcen und Performance.



  • hier mal ein pseudocode:

    class Zeichenbar
    {
         virtual void zeichne() // nicht abstract, nur virtuell!
         {
              // ist leer u. macht nichts!
         }
    };
    
    class ClassB : public Zeichenbar
    {
         // keine zeichne()-Methode implementieren,
         // wenn ClassB nichts zeichnen soll!
    };
    
    class ClassX : public Zeichenbar
    {
         void zeichne()
         {
             // hier kommen Zeichenmethoden rein!
         }
    };
    
    // irgendwo im Programm...
    ClassB *b = new ClassB();
    ClassX *x = new ClassX();
    
    b->zeichne(); // dieses Objekt ruft die leere zeichne()-Methode von Klasse Zeichenbar auf
    x->zeichne(); // dieses Objekt ruft die zeichne()-Methode von ClassX auf
    

    So brauchst du dir keine Gedanken machen, ob man am ende was auf dem Screen sieht. Jedes Objekt zeichnet sich selbst mit den Methoden die es implementiert hat, gibts keine Implementation, wird die leere virtuelle Methode aufgerufen. Hier gilt immer, das Objekt soll sich um seinen eigenen Kram kümmern.



  • Schau mal in Bruce Eckel, The STL Made Simple (1999). Da findest Du die shape- Klassenhierarchie mit upgecasteten Zeigern im Vektor ( vector<shape*> ). Basisklasse dort abstrakt. Die Draw-Methode läuft polymorph via ((vector<shape>::iterator))->draw(...). Vielleicht ist das was für Dich.


Anmelden zum Antworten