Wo wird hier der Kopierkonstruktor aufgerufen??



  • Original erstellt von Helium:
    Wo in dem Code sollte denn sonst eine Copy-C'tor aufgerufen werden:

    Ich habe nur gesagt, dass man im + bzw. = operator in der Regel keinen Copy-Constructor (der eigenen Klasse) braucht.

    Original erstellt von Helium:
    Du übersiehst außerdem den Pointer in der Klasse. Das heißt er wird wohl neuen Speicher alokieren müssen (Nicht i +, aber im Gleich). Und da wird auf jedenfall eine Copy-C'tor fällig.

    Der Pointer ist aber vom Typ Lnode. Beim alloziieren wird kein Copy-Konstruktor aufgerufen, nur beim initialisieren.



  • Nein, umgekehrt. In der Regel macht man das so in der Art.

    Set& Set::operator=(const Set& set) {
    m_sonstwas1 = set.m_sonstwas1;
    m_sonstwas2 = set.m_sonstwas2;
    return *this;
    }

    Set::Set(const Set& set) {
    *this = set;
    }

    Nein so macht man das in der Regel (oder im Allgemeinen) nicht.
    Ein Zuweisung ist etwas anderes als eine Konstruktion.

    Was man hingegen häufig macht ist den copy-assignment Operator über den Copy-Konstruktor zu implementieren:

    class Foo
    {
    public:
        Foo(const Foo& rhs);
        void swap(const Foo&) /* throw() */;
        Foo& operator=(const Foo& rhs)
        {
             Foo temp(rhs);
             swap(temp);
             return *this;
        }
    };
    

    Wo in dem Code sollte denn sonst eine Copy-C'tor aufgerufen werden:

    Set menge1, menge2, menge3;
    menge3 = menge1 + menge2;

    Ganz einfach:

    Set operator+(const Set &menge1, const Set &menge2);
    

    Der operator+ liefert ein Set-Objekt by value. Und was bedeutet value-Return doch noch gleich? Richtig. Der Copy-Ctor der Klasse *muss* aufrufbar sein, da ein value-Return konzeptionell *immer* über den Copy-Ctor geschieht.
    Würde dort:

    Set menge3 = menge1 + menge2;
    

    dann könnte das Ergebnis der Addition direkt in den Speicher von menge3 konstruiert werden (RVO). Es würde wohl kein Copy-Ctor aufgerufen werden. Trotzdem muss er aufrufbar sein.

    Da wir in diesem Fall aber eine Zuweisung und keine Initialisierung haben, fällt die Möglichkeit für eine in-place-construction flach.
    Das temporäre Ergebnis-Objekt der Addition wird per Copy-Ctor-Aufruf erzeugt.

    [ Dieser Beitrag wurde am 02.06.2003 um 12:15 Uhr von HumeSikkins editiert. ]

    [ Dieser Beitrag wurde am 02.06.2003 um 12:16 Uhr von HumeSikkins editiert. ]



  • Also erstmal vielen Dank für die vielen Zuschriften!

    Ich kopiere mal zunächst die beiden Funktionen hier rein:

    Vorweg vielleicht noch eins: Der Code ist sicherlich nicht so optimal, ich stecke noch in den Kinderschuhen, was C++ angeht. Aber darum bin ich ja hier! 😉

    Set operator+(const Set &menge1, const Set &menge2)
    {
        Set unionSet;
    
        Lnode *pnode = menge1.pstart;
    
        while (pnode)
        {
            unionSet.insert(pnode->val);
            pnode = pnode->next;
        }
    
        /* Menge 2 in neue Liste kopieren */
        /* Die Funktion insertSetElement kuemmert sich um doppelte Elemente */
        pnode = menge2.pstart;
    
        while (pnode)
        {
            unionSet.insert(pnode->val);
            pnode = pnode->next;
        }
    
        return unionSet;
    }
    

    und

    Set &Set::operator=(const Set &menge)
    {
        if (&menge != this)
        {
    
            Lnode *pnode = menge.pstart;
    
            empty();
    
            while (pnode)
            {
                insert(pnode->val);
                pnode = pnode->next;
            }
        }
        return *this;
    }
    

    Übrigens: Kann mir bitte einer sagen, wie ich den Text in C++ -Stil hier aussehen lassen kann? Hab das nicht hinbekommen! Hab das markiert und dann unten auf den C++ Button gedrückt, hat aber nicht funktioniert.

    Aber ich glaube ich habe das jetzt verstanden!
    In der operator+ Funktion wird ein "Objekt" geschaffen und mittels Copy-C'tor an den (diese Funktion) aufrufenden Teil zurück"kopiert". Oder?

    BK
    Bitte Code-Tags verwenden!

    [ Dieser Beitrag wurde am 02.06.2003 um 12:58 Uhr von HumeSikkins editiert. ]



  • Ähm, der rote Smiley war keine Absicht!
    Wie kann ich das editieren?
    Danke.



  • Original erstellt von HumeSikkins:
    **Nein so macht man das in der Regel (oder im Allgemeinen) nicht.
    Ein Zuweisung ist etwas anderes als eine Konstruktion.

    Was man hingegen häufig macht ist den copy-assignment Operator über den Copy-Konstruktor zu implementieren:

    class Foo
    {
    public:
        Foo(const Foo& rhs);
        void swap(const Foo&) /* throw() */;
        Foo& operator=(const Foo& rhs)
        {
             Foo temp(rhs);
             swap(temp);
             return *this;
        }
    };
    

    **

    Und wo liegen bei deiner Variante die Vorteile??? Es ist doch eigentlich das selbe nur mit einem temporären Objekt... 😕



  • Original erstellt von MaSTaH:
    Und wo liegen bei deiner Variante die Vorteile??? Es ist doch eigentlich das selbe nur mit einem temporären Objekt... 😕

    es werden keine default ctoren aufgerufen.

    stell dir mal vor die klasse beinhaltet ein objekt als member.

    bei deiner version wäre es das selbe wie wenn man

    Klasse obj;
    obj=foo;

    schreiben würde, bei Hume ist
    Klasse obj(foo);
    effizienter als
    Klasse obj;
    obj=foo;



  • Es ist doch eigentlich das selbe

    Nö. In deinem Fall werden beim Copy-Ctor erstmal alle Member-Objekte per Default-Ctor und PODs überhaupt nicht initialisiert.
    Das ist häufig schonmal ein Performance-Nachteil (Default-Initialisierung + Assignment statt einfach einmal Initialisierung mit dem richtigen Wert) und einen viel schöneren Nachteil der daraus resultiert findest du hier erklärt:
    http://www.c-view.org/tech/pattern/cpptips/cpyctor_assign



  • Original erstellt von Shade Of Mine:
    es werden keine default ctoren aufgerufen.

    Ich stehe jetzt auf dem Schlauch. Wo werden bei mir denn Default-C'tors aufgerufen?



  • Original erstellt von HumeSikkins:
    In deinem Fall werden beim Copy-Ctor erstmal alle Member-Objekte per Default-Ctor und PODs überhaupt nicht initialisiert.

    Ups, jetzt wo du es sagst... 🙄 🙂



  • Ganz einfach:

    Set operator+(const Set &menge1, const Set &menge2);

    *Vor den Kopf schlag*


Anmelden zum Antworten