wie elegant copy anlegen



  • Hallo zusammen,

    ich habe eine Methode, welche ein abstraktes B bekommt. Dann habe ich eine Liste, welche Pointer auf B's speichert. In der Liste möchte ich eine Kopie des B's speichern. Da die B's abstrakt sind, kann ich dies nur über eine dup() Methode erreichen, welche allerdings ein A (Oberklasse von 😎 speichert. Mein Code sieht wie folgt aus:

    void
            Transfer::storeMessage(B & msg){
    
                //not already stored?
                if(!retransmitMessageQueue.contains(msg)){
    
                    //store the message
                    //A* dup() const;
                    B * copyMsg = (B*)msg.dup();  //<<--- geht dies eleganter?
                    retransmitMessageQueue.add(copyMsg);
                }//end if
            }
    

    Aufgerufen wird dann die Methode ala store(c), wobei c vom Typ C ist, welches von B erbt.
    Geht die markierte Stelle eleganter??

    Gruß
    sven_


  • Mod

    Du kannst den Cast weglassen, wenn deine Klassenhierarchie wirklich so aussieht, wie du beschreibst. Falls der Compiler sich beschwert, dann hast du irgendwo etwas falsch gemacht. Aber stelle ihn dann niemals durch einen reinterpret_cast (und das ist solch ein C-Cast im schlimmsten Falle) ruhig! In der Regel hat er nämlich recht.

    Ansonsten ist dieses Vorgehen so durchaus üblich. Clone Pattern wird das auch gerne genannt.



  • Hallo SeppJ,

    clone Pattern, wieder was neues. 😉

    Ohne cast bekomme ich:

    error: invalid conversion from ‘A*’ to ‘B*’
    

    Mein B ist:

    class B : public A {...}
    

    ???
    sven



  • Nachtrag:

    Die dup Methode sieht so aus:

    [cpp]
    virtual A * dup() const = 0;
    [cpp]

    Gruß


  • Mod

    sven_ schrieb:

    Nachtrag:

    Die dup Methode sieht so aus:

    virtual A * dup() const = 0;
    

    Gruß

    Und ich wette die Implementierung in B gibt auch einen A* zurück, oder? Hier kommt jetzt der große Trick: Die Rückgabewerte von virtuellen Methoden dürfen in den abgeleiteten Klassen auch spezialisiertere Versionen des Rückgabetyps aus der Basisklasse zurück geben (unter bestimmten Regeln, die du irgendwo nachlesen kannst). Das heißt, das dup in B darf einen B* zurück geben! Problem gelöst.

    Das nennt man covariant return types. Hier eine Erklärung, sogar genau anhand deiner Problemstellung (denn diese ist wohl die häufigste Anwendung dafür):
    http://www.lwithers.me.uk/articles/covariant.html
    Für mehr Infos einfach mal nach dem Stichwort googeln.



  • Hallo SeppJ,

    vielen Dank. Wieder was gelernt. Tolles Forum hier. Ich dank dir vielmals!!!!!

    🙂

    Vielen Dank.
    sven


  • Mod

    SeppJ schrieb:

    Das nennt man covariant return types. Hier eine Erklärung, sogar genau anhand deiner Problemstellung (denn diese ist wohl die häufigste Anwendung dafür):
    http://www.lwithers.me.uk/articles/covariant.html

    Hat das eigentlich schon mal jemand für etwas anderes als clone() verwendet?



  • SeppJ schrieb:

    Das nennt man covariant return types. Hier eine Erklärung, sogar genau anhand deiner Problemstellung (denn diese ist wohl die häufigste Anwendung dafür):
    http://www.lwithers.me.uk/articles/covariant.html
    Für mehr Infos einfach mal nach dem Stichwort googeln.

    In dem von dir verlinkten Dokument gibt es einen Fehler:

    Often, the derived class has a polymorphic function which returns a more specific (i.e. more derived) type than the base class. This is per fectly legal, since the pointer is automatically downcast to the base class type.

    Downcasten zu einem Basisklassenpointer? Das ist doch ein upcast?


  • Mod

    Oh nein! Ruft die Polizei! Ein kleiner Verdreher in einer inoffiziellen Terminologie wo trotzdem jeder wusste, was gemeint ist, weil es direkt dahinter noch einmal ausdrücklich beschrieben steht. Das ist der Untergang des Abendlandes! Morgen werden wir wieder auf Bäumen leben.



  • SeppJ schrieb:

    Oh nein! Ruft die Polizei! Ein kleiner Verdreher in einer inoffiziellen Terminologie wo trotzdem jeder wusste, was gemeint ist, weil es direkt dahinter noch einmal ausdrücklich beschrieben steht. Das ist der Untergang des Abendlandes! Morgen werden wir wieder auf Bäumen leben.

    Downcast und Upcast vertauschen? Das ist doch nich' gut ist das doch nich'! 😡

    🤡
    Bin schon still.


Log in to reply