Herausfinden, wer die Callbackfunktion ausgeführt hat.



  • "...Eine Klasse Y wird von mehreren Klassen benachrichtigt…" von den Observer Klassen?

    Warum übergibst Du der Methode ErrorOccured nicht einfach eine Referenz auf die jeweilige Observer Klasse. Dann hat ErrorOccured gleich das betreffende Objekt?



  • @Helmut-Jakoby

    Sehr guter Hinweis.
    Danke, muss ich mal ausprobieren!



  • Der Vorschlag war eigentlich schon in der ersten Antwort von @firefly enthalten 😉



  • @hustbaer Hast recht, aber ich muss den Vorschlag mit der Übergabe einer Referenz auf ein Objekt revidieren.
    Denn, ich will in Abhängigkeit eines Objekts ein Bit setzen. Ich versuche es mal zu erklären:

    memberVariable ist 8 Bit groß. Jedes Bit wird einem Observer zugeordnet.
    Observer 1 setzt memberVariable bei true den Bit 1 auf 1 und bei false löscht er es wieder.
    Observer 2 setzt Bit 2
    usw
    bis Observer 8.

    Warum das ganze?
    Weil angenommen, Observer 1 bis 8 werden nacheinander ausgeführt, dann würde, wenn Observer 1 einen Fehler meldet, dann bestünde die Gefahr, dass die anderen Observer die memberVariable von true auf false setzen. Daher verodere ich die memberVariable.
    Mit einer Referenz auf ein Objekt kann ich kein Bit setzen.
    Ich kann höchstens nebem dem boolschen Wert eine Art Objektnummer 1 bis 8 mit übertragen. Das Problem ist, ich muss bei der Übergabe der Objektnummern höllisch aufpassen, die Objektnummern nicht doppelt zu belegen.

    Ich dachte, da ich ein blutiger C++ Anfänger bin, dass es eine elegantere Methode gibt.....



  • Ist sichergestellt, dass es maximal 8 Observer gibt?
    Weil wenn ja könnte man folgendes machen.
    Alle Observer leiten von einer Basis klasse ab.
    Die Basisklasse enthält einen member welcher die "Objektnummer" darstellt. Und stellt eine get-Methode bereit.
    Im Construktor der Basisklasse wird mit hilfe einer statischen variable die "Objektnummer" generiert.

    Die "Error occured " methode nimmt dann eine reference von dieser Basisklasse als zusätzlichen Parameter

    Das ganze funktioniert nur wenn garantiert ist, dass das erstellen der Observer Instanzen nicht parallel erfolgt (z.b. via threads). Bzw. man müsste dann die Generierung der "Objektnummer" serialisieren (z.b. via mutex)

    Diese Basisklasse könnte im groben so aussehen.
    Wichtiger Hinweis! Folgenden code sollte man so nicht direkt übernehmen sondern eher nur als ein beispiel verstehen, da ich hier nicht alle möglichen fallstricke bedacht habe.

    class objektnumber {
        private:
            int id;
        public:
            int getId()const{ return id;}
        protected:
            objectnumer() {
                static int nextId = 0;
                id = nextId;
                ++nextId;
            }
    }
    

    Das die erste id/objektnummer 0 ist, kann man dann folgendes recht einfach machen um das passende bit zu setzen/zu löschen:

    void ErrorOccured(bool isError, const objektnumber& object)
    {
        if (isError) {
            memberVariable |= 1<<object.getId();
        } else {
            memberVariable &= ~(1<<object.getId());
        }
        
    }
    


  • @firefly Ich danke dir für die Idee.
    Das werde ich austesten.

    Die Id Nummer müssten aber in 2er Potenzen verteilt werden.
    Dh Objekt 1 ist 1, Objekt 2 ist 2, Objekt 3 ist 4.
    Id Nummer = 2^(Anzahl der Objekte-1)



  • Du mußt nur beim ver'oder'n die 2er-Potenz erstellen:

     memberVariable |= (1 << n); // n: 0 ... 7
    

    Wenn du doch lieber Referenzen statt der Zahlenwerte übergeben willst, dann erzeuge dir eine std::map<const Class*, int> (welche du einmalig füllst und dann in deiner Funktion aufrufst).



  • @TK-KT sagte in Herausfinden, wer die Callbackfunktion ausgeführt hat.:

    @firefly Ich danke dir für die Idee.
    Das werde ich austesten.

    Die Id Nummer müssten aber in 2er Potenzen verteilt werden.
    Dh Objekt 1 ist 1, Objekt 2 ist 2, Objekt 3 ist 4.
    Id Nummer = 2^(Anzahl der Objekte-1)

    Nein darf sie nicht. Die nummer stellt dar um welches bit es sich handelt.
    Durch die "bitwise shift operation" (<<) in der ErrorOccured wird dann ein wert generiert in dem nur das entsprechende Bit gesetzt wird.
    2 Beispiele:
    Wenn ID 7 ist, dann werden alle gesetzten Bits um 7 stellen nach links verschoben.
    In diesem Falle ist das Ergebnis dann binär 1000 0000 oder dezimal 128.
    Wenn die ID 0 ist, dann bleibt es bei dem wert von 1 welches binär 0000 0001 (Bei 8Bit) entspricht.

    Meine Erklärung wie die "bitwise shift operation" funktioniert ist sehr vereinfacht. Sollte aber ausreichen um das Prinzip zu verstehen.



  • @Th69 sagte in Herausfinden, wer die Callbackfunktion ausgeführt hat.:

    Du mußt nur beim ver'oder'n die 2er-Potenz erstellen:

     memberVariable |= (1 << n); // n: 0 ... 7
    

    Siehe meine ErrorOccured beispiel Implementierung wo genau das passiert 😉



  • @firefly: Sorry, nicht gesehen (manchmal werden Beiträge nicht automatisch angezeigt, wenn die Seite geöffnet ist und ich muß nochmal explizit F5 drücken).


Anmelden zum Antworten