Object identifizieren



  • Somersault schrieb:

    ...
    irgendwann möchte ich aber diese Objekte wieder rausholen und wissen was es ist, also ob A, B oder C. ...

    Die entscheidende Frage ist: Wozu ?
    (üblicherweise braucht man das nämlich nicht mehr zu "wissen", sondern will etwas damit tun - und genau dafür sind "virtual functions" ("Polymorphie") gedacht und ideal.)

    Gruß,

    Simon2.



  • Ja, in der Regel wollte ich sowas triviales machen wie: berechne, je nachdem hätte das Programm die richtige Methode verwendet.

    Jetzt bekomme ich aber über das Netzwerk ständig Aktualisierungen rein...
    d.h. A, B oder C können sich entweder ändern oder ganz verschwinden.

    Ich habe also meinen vector std::vector<Buchstaben *> und möchte z.B. alle Objekte der Klasse A überprüfen.. Das Ziel ist, jene rauszuschmeißen, die nicht mehr gebraucht werden. Somit möchte ich schon von vornherein die andere Objekte unberührt von dieser Überprüfung lassen. Quasi überspringen.

    Cool wäre sowas wie:

    std::vector<Buchstaben *> Buchstabensuppe;
    
    // in Schleife
    if (Buchstabensuppe.at(i).getObject.getClassNameAsString == "A"){
          // überprüfe
    }
    

    Aber ich glaube sowas gibts wohl nicht in C++;



  • Hallo

    Nein sowas wäre gar nicht cool, das wäre wegen dem extra String-Vergleich ineffizient (da ist sogar dynamic_cast effizienter).
    Höre auf die Vorposter, und überleg dir lieber ob dein Konzept noch zur Aufgabe passt. Als einfache Lösung könntest du die Basisklasse Buchstaben um eben die abstrakte oder virtuelle Methode erweitern die du in den Unterklassen brauchst.

    bis bald
    akari



  • std::vector<Buchstaben *> Buchstabensuppe;
    
    class Buchstabe{
    protected:
    virtual char GetType();
    };
    
    class A : public Buchstabe{
    public:
     char GetType(){ return 'A'};
    };
    
    class B : public Buchstabe{
    public:
     char GetType(){ return 'B'};
    };
    
    class C : public Buchstabe{
    public:
     char GetType(){ return 'C'};
    };
    
    //Schleife
    if (Buchstabensuppe.at(i).GetType()== 'A'){
          // überprüfe
    }
    


  • @akari: macht ein String (oder Char) Vergleich das ganze so ineffizienter?

    Der Sinn des ganzem was ich tun soll ist das ganze schneller zu machen...
    Was für eine Ironie 😃



  • Hallo

    Ein Vergleich von Strings bedeutet immer das alle Buchstaben nacheinander verglichen werden, bis der erste Unterschied gefunden wird. Im Vergleich dazu können Integer in einem Durchgang verglichen werden.
    dynamic_cast ist selber auch nicht das Optimum, da ziehe ich dann doch virtuelle Funktionen in der Basisklasse vor, wie zu letzt von Boris gezeigt. Allerdings ohne noch über den Umweg einer Namensprüfung, sondern gleich direkt die für dich interessante Methode

    class Buchstabe
    {
      ...
      // Deine Prüfung für eine Instanz, Parameter je nachdem was du brauchst
      virtual bool Check(...) const = 0; 
    };
    
    class A
    {
      ...
      // Implementation für diese Klasse, im einfachsten Fall true oder false zurückgeben
      virtual bool Check(...) const
      {
        return true;
      } 
    }
    

    bis bald
    akari



  • vielen Dank!

    ich denke, jetzt verstehe ich es (fast).

    Die Variente mit dem bool funktioniert aber nur bei 2 Klassen, die Erben, oder? -wenn ich mehr habe, und die alle Unterscheiden will, brauch ich 'chars' bzw Integer, oder?

    Ich bin ein ziemlicher Neuling mit C++. Darf ich kurz fragen ob es ein Unterschied, zwischen:

    virtual bool Check() = 0;
    und
    virtual bool Check() const = 0;
    gibt?
    Bedeutet dies, dass die Fkt. Konstant ist? 😕

    Danke für die Hilfe!



  • Somersault schrieb:

    virtual bool Check() const = 0;
    ...
    Bedeutet dies, dass die Fkt. Konstant ist? 😕

    Es bedeutet, das die Funktion keine Membervariablen ändert und ist somit auch aufrufbar, und kann daher auch auf ein konstantes Objekt angewendet werden.

    Siehe hierzu auch const-correctness.

    cu André



  • Also, der Ansatz über die Basisklasse zu gehen, wenn eigentlich abgeleitete Objekte benötigt werden, ist grundsätzlich erstmal suboptimal.
    Ich würde jeden Typen in einer eigenen Liste verwalten, und dann dafür Funktionen überladen, sofern möglich. Wenn nicht, muss man über unterschiedliche Funktionsnamen unterscheiden. Wie dem auch sei, der Aufwand ist auch nicht größer, als jeden Typen mit einem selbstgebastelten TypeID-System zu prüfen. Und performanter ist er mit Sicherheit.

    Mit ein paar Informationen darüber, wie die Auswahl der zu löschenden Objekte zustande kommt, könnte man vielleicht noch weiter helfen.



  • Somersault schrieb:

    Cool wäre sowas wie:

    std::vector<Buchstaben *> Buchstabensuppe;
    
    // in Schleife
    if (Buchstabensuppe.at(i).getObject.getClassNameAsString == "A"){
          // überprüfe
    }
    

    Übergib doch die Aktualisierungen an die einzelnen Objekte in deinem Container und die entscheiden dann selber was zu tun ist (Polymorphie ausnutzen).
    Oder du machst sowas wie das visitor-Pattern.


Anmelden zum Antworten