Datentyp abfragen



  • Ich eine Funktion bauen möchte die je nach übergebenem Objekt zusätzliche Befehle ausführt oder weglässt.

    Ich hätte eigentlich ja so etwas erwartet.

    int add_property(Class &obj){
      if(obj==KlasseA)
    }
    

    Nachdem ich mich im Netz umgeschaut habe bin ich ein wenig verwirrt. Manche Quellen empfehlen RTTI. Wikibooks schreibt das RTTI madig ist und dass man es gefälligst meiden sollte wenn es geht.

    Es gibt auch einen Ansatz mit sizeof(obj).

    Gibt es eine übliche Vorgehensweise für mein Problem oben ohne dass ich für jede Klasse ein Template anlegen muss, oder ist es besser doch für jede Klasse ein Template anzulegen?





  • Mit Templates hat das nichts zu tun.

    Aber vermeide explizite Typunterscheidungen mit if , du handelst dir dabei einige Probleme ein. Bei einem guten Design ist es normalerweise nicht nötig, den Typ abzufragen. Alternativen wurden ja bereits genannt.



  • ogrrrrrrg schrieb:

    Google: laufzeit polymorphie
    Google: visitor pattern

    Ich habe mir ein wenig Zeit genommen um das ganze durchzulesen. Jetzt weiß ich nicht ob ich mich undeutlich ausgedrückt habe oder ich nicht die richtigen Schlüsse aus den Links ziehen kann.

    Hier ein abstraktes Beispiel meines Vorhabens.

    // Basisklasse mit zwei Eigenschaften
    class Base{
    private:
      int a;
      int b;
    public:
      void set_a(int val);
      int get_a();
      ...
    }
    
    class Child2:public Base{
    private:
      int c;
    public:
      void set_c(int val);
      int get_c();
    }
    
    class Child2:public Base{
    private:
      int d;
    public:
      void set_d(int val);
      int get_d();
    }
    

    Ich habe mehrere Objekte wie Child1/2 die allesamt Base Eigenschaften Tragen und noch ihre eigenen Eigenschaften mitbringen. Diese Eigenschaften möchte ich nun aus einer XML Datei parsen sie so aussieht:

    <Child1 a="1" b="2" c="3" />
    <Child2 a="4" b="5" d="6" />
    

    Bisher habe ich (geplant) ein Objekt von Child1/Child2 zu erstellen und Dieses an die Funktion weiterzureichen. Die Funktion soll über eine while Schleife die gemeinsamen Eigenschaften herauslesen. Damit hätte ich aber noch nicht die speziellen Eigenschaften... fällt jemandem eine bessere XML/Klassenstruktur/Funktion/Vorgehensweise ein um dieses Vorhaben zu verwirklichen? XML unterstützt ja bis dato keine Vererbung.

    Bin für jeden Tipp dankbar.



  • du kannst der basisklasse eine methode serialize geben und jedes kind schreibt dann in dieser sein xml raus. oder du nimmst eine map, wenn es nur so einfache typen sind



  • Entweder du baust über ein RTTI System einen entsprechenden Generischen Loader/Saver, was wirklich dirty ist, habs das einmal gemacht und nie wieder, oder aber so wie ich im Moment ein ähnliches System gebaut habe:

    Du nimmst deine Basisklasse die hat z.B. saveMeListType save(saveMeListType saveList)

    die haut dann in saveList alles das rein, per push, was die Basisklasse so mit sich bringt und speicherbar sein soll, bei allen abgeleiteten Klassen.

    Nun hast du in der abgeleiteten Klasse auch eine Funktion saveMeListType save(saveMeListType saveList) und fügst da in die Liste alles ein, was du nun haben willst, und rufst von der entsprechenden Basisklasse die save Funktion auf, woraufhin dann hierarchisch alle Daten in die Liste gespeichert werden.

    Dann musst du nur noch eine Funktion basteln, die diese Liste interpretiert und entsprechend Speichert.

    Das Laden währe dann bei dem System ähnlich.

    der saveMeListType kann ja dann sowas wie list<saveMeType> sein und saveMyType kann so komplex sein wie du es halt brauchst um einen einzelnen Datensatz entsprechend laden und speichern zu können, bze. die Eigenschaften des Datensatzes einzeln zu unterscheiden. Am ende kann man daraus einen generishcen Serializer basteln, wo man als abgeleitete spezialisierte Klasse einen XMLSerializer hat. oder einen TextFileSerializer, das sind dann Dinge von ein paar stunden/Minuten je nachdem wie Komplex alles ist. 🙂

    Hoffe das das etwas weiterhilft und in die Richtung geht die du suchst.

    Möglich das es auch einfacher geht aber es gibt ja Unmengen Ansätze für solche Systeme.

    MFG
    Blackskyliner



  • Ich denke dass ich mit den gegebenen Antworten weiterarbeiten kann.

    Danke an Alle für die Mühe



  • Nun hätte ich doch noch eine Frage

    Meine Lösung sieht so aus:

    //Generelle Eigenschaften setzen
    bool set_prop(Base &obj, xmlnode node){
    ...
    if(node=NULL) return set_props(obj);
    else return set_props(obj,node);
    }
    //Spezielle Eigenschaften setzen
    bool set_props(Child1 &obj){ ... if(allesok) return true; else return false; }
    bool set_props(Child2 &obj, xmlnode *node) { ... if(allesok) return true; else return false; }
    

    Jetzt bringt mir der Compiler bei der Funktion für die speziellen Eigenschaften folgenden Fehler:

    error C2664: 'set_props(Child1&)' : cannot convert parameter 1 from 'Base' to 'Child1 &'
    error C2664: 'bool set_props(Child2&,xmlnode*)' : cannot convert parameter 1 from 'Base' to 'Chil2 &'
    

    Wieso nimmt er an das "obj" keine Referenz ist?
    Ich empfange die Variable obj doch als Referenz in set_prop und meine funktionen set_props empfangen doch auch nur Referenzen?



  • typfrager schrieb:

    if(allesok) return true; else return false;
    

    Abgekürzt auch gern gesehn als

    return allesok;
    

    Zu deinem Fehler, da hast du das Vorgehen mit der Laufzeitpolymorphie wohl noch nicht ganz verstanden.
    mach die "setprops"-Funktionen zu virtuellen Methoden der Child-Klassen und der Basis-Klasse. Die Laufzeitpolymorphie sorgt dann dafür dass je nachdem von welchem Typ die Base-Referenz wirklich ist die richtige Methode aufgerufen wird.



  • Es existiert keine implizite Konvertierung von der Basisklasse zur abgeleiteten Klasse (nur umgekehrt). Du müsstest also downcasten und hast wieder das Designproblem.

    Könntest du etwas mehr von deinem Code zeigen (keine Funktionsimplementierungen, nur Schnittstellen)?



  • pumuckl schrieb:

    Zu deinem Fehler, da hast du das Vorgehen mit der Laufzeitpolymorphie wohl noch nicht ganz verstanden.

    Bisher habe ich es vermieden die Methoden in der Basisklasse zu implementieren. Die Basisklasse ist mMn ein Datenkontainer und XML ist etwas, was nichts mit der Datenhaltung zu tun hat.

    So schleppe ich, wenn ich die Klasse irgendwo anders verwende, unnötige XML Parser mit.

    pumuckl schrieb:

    mach die "setprops"-Funktionen zu virtuellen Methoden der Child-Klassen und der Basis-Klasse. Die Laufzeitpolymorphie sorgt dann dafür dass je nachdem von welchem Typ die Base-Referenz wirklich ist die richtige Methode aufgerufen wird.

    Mittlerweile glaube ich, dass ich es entgegen meinen Bedenken, tatsächlich machen sollte...

    Nexus schrieb:

    Könntest du etwas mehr von deinem Code zeigen (keine Funktionsimplementierungen, nur Schnittstellen)?

    Zu dieser Lösung existiert kein Code. Ich habe es bisher versucht abstrakt zu lösen bevor ich in funktionsfähigen Code eingreife.

    Nexus schrieb:

    Es existiert keine implizite Konvertierung von der Basisklasse zur abgeleiteten Klasse (nur umgekehrt). Du müsstest also downcasten und hast wieder das Designproblem.

    Das ist ein guter Hinweis. Dann wäre doch die Lösung die passende Methode für die Spezialeigenschaften aufzurufen die dann wiederrum generelle Eigenschaften aufruft?



  • typfrager schrieb:

    Bisher habe ich es vermieden die Methoden in der Basisklasse zu implementieren. Die Basisklasse ist mMn ein Datenkontainer und XML ist etwas, was nichts mit der Datenhaltung zu tun hat.

    Hier liegt dein Verständnisproblem. Du musst die Methoden in der Basisklasse nicht implementieren, weil diese dann abstrakt wären. Sie würden lediglich das Interface spezifizieren, das in abgeleiteten Klassen implementiert werden könnte.

    Lies dich etwas in Laufzeitpolymorphie und virtuelle Funktionen ein, dann wird dir wahrscheinlich auch klarer, was wir meinen.



  • Nexus schrieb:

    ...

    Mein Fehler. Ich will es weder in der Basisklasse noch in den Kindern weil sie im Moment ein ganz anderes Projekt bilden. Ich will es lediglich wiederverwerten. Ändert aber wahrscheinlich nichts an der Tatsache dass ich es doch machen sollte ihr das vorgeschlagen habt.


Anmelden zum Antworten