Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Copyconstructor

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
03.11.2004, 18:57 Uhr
rejo



Hallo Leute würd gern mal wissen was ein Copyconstructer macht...?

Danke schon mal im vorraus
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
03.11.2004, 20:14 Uhr
(un)wissender
Niveauwart


Der macht das, was du implementierst. In der Regel sollte er das übergebene Objekt kopieren oder etwas in der Art.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
03.11.2004, 21:36 Uhr
rejo



aha... hat jemand ein kleines bsp. für mich
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
03.11.2004, 22:08 Uhr
(un)wissender
Niveauwart


Einen Kopierkonstuktor und einen Zuweisungsoperator brauchst du immer dann, wenn mehr als nur schlicht die Daten der Klasse bitweise kopiert werden müssen.
Default gibt es die beiden immer, aber sie kopieren nur bitweise, wenn du also was anderes willst, dann musst du sie überschreiben.
Eigentlich kommen Kopierkonstuktor, Zuweisungsoperator und Destruktor immer im Dreifachpack.


C++:
class Test
{
public:
    Test() : myint(new int(0)) {}
    ~Test() { delete myint; }
    
    //copy constuctor
    Test(const Test& test) : myint(new int(*test.myint)) {}

    //zuweisung
    Test & operator=(const Test& test)
    {
        int * temp = new int(*test.myint);
        delete myint;
        myint = temp;
        return *this;
    }

private:
    int * myint;
};


--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
03.11.2004, 22:28 Uhr
ao

(Operator)


Klar, weswegen man die drei hier braucht?

Test enthält einen Zeiger, wenn man den bitweise kopiert, hat man zwei Zeiger (einen in der Original-Instanz, einen in der Kopie-Instanz), die auf denselben Speicherort zeigen.

Problem: Die Instanzen wären nicht voneinander unabhängig, Änderungen an der einen würden auch auf die andere wirken. Und beim Zerstören würde der Speicher, auf den die Pointer zeigen, zweimal freigegeben -> Heap kaputt, ganz schlecht.

Ich füg mal noch eine Überladung für operator= hinzu, damit man mit der Klasse auch was anfangen kann:

C++:
class Test
{
public:
    Test() : myint(new int(0)) {}
    ~Test() { delete myint; }
    
    //copy constuctor
    Test(const Test& test) : myint(new int(*test.myint)) {}

    //zuweisung
    Test & operator=(const Test& test)
    {
        int * temp = new int(*test.myint);
        delete myint;
        myint = temp;
        return *this;
    }

    Test & operator=(int nValue) {*myint = nValue; return *this;}

private:
    int * myint;
};



... und jetzt machen wir was damit:


C++:
int main (void)
{
    Test t1;    // Instanz erzeugen und Default-konstruieren
    t1 = 5;     // Wert zuweisen

    Test t2 (t1);    // andere Instanz erzeugen und als Kopie von t1 konstruieren.
                   // Hier wird der Copy-Ctor verwendet.
                   // t2 hat jetzt auch den Wert 5, jedoch an einer anderen Stelle im Speicher,
                   // das ist wichtig.

    t1 = 89;    // Wert von t1 ändern; t2 ist immer noch 5.

    return 0;
}                 // Hier werden für t1 und t2 die Destruktoren aufgerufen. Das geht gut, weil
                  // jede Instanz ihren eigenen Speicher besitzt.


Dieser Post wurde am 03.11.2004 um 22:29 Uhr von ao editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
03.11.2004, 23:20 Uhr
(un)wissender
Niveauwart


Gut, ich bin mit meiner Erklärung ein wenig kurz angebunden gewesen, danke ao.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
04.11.2004, 00:24 Uhr
virtual
Sexiest Bit alive
(Operator)


Liebe Leute,
das macht man aber so nicht: keiner der hier vorgestellten Zuweisungsoperatoren ist exceptionsicher!
Normalerweise implementiert man eine swap Methode, die die Instanzattribute mit denen des übergebenen Objekts tauscht:

C++:
void Test::swap(Test& other) {
    std::swap(other.myint, myint);
}


Und dieses swap wird dann wie folgt verwurschtelt:

C++:
Test& Test::operator = (const Test& other) {
    Test temp(other);
     swap(temp);
     return *this;
}


--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
04.11.2004, 01:57 Uhr
ao

(Operator)



Zitat von virtual:
Liebe Leute,
das macht man aber so nicht

Au weia, mal wieder voll ins Fettnäpfchen gestiegen (schäm). Dabei wollte ich doch bloß erklären, wozu ein Copy-Konstruktor gut ist (so hab ich die Ursprungsfrage verstanden).

Na los: Was meinst du mit "exceptionsicher" und warum braucht man das hier?

ao
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
04.11.2004, 07:29 Uhr
virtual
Sexiest Bit alive
(Operator)


Hallo ao,

sorry, war geytern schon spät:


C++:
  Test & operator=(const Test& test)
    {
        int * temp = new int(*test.myint);
        delete myint;
        myint = temp;
        return *this;
    }


Ist exceptionsicher, da habe ich mich vertan. NichtExceptionsicher wäre gewesen:

C++:
  Test & operator=(const Test& test)
    {
        delete myint;
        myint = new int(*test.myint);
        return *this;
    }


Der Grund dürfte hier klar sein: das new kann schiefgehen (std::bad_alloc exception). Da es erst nach dem delete aufgerufen wird, hinterläßt es das Objekt links vom Gleichheitszeichen (also this) im verwüsteten Zustand.

Der von mir gezeigte Code macht das gleiche wie der Deinige, nur wesentlich umständlicher; allerdings auf eine recht generische Art; er läßt sich unverändert auch anwenden, daß die Testklasse eine große Zahl von Membervariablen hätte, die eine tiefe Kopie erfordern...
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
04.11.2004, 07:53 Uhr
(un)wissender
Niveauwart



Zitat von virtual:

Ist exceptionsicher, da habe ich mich vertan.



Das will ich meinen! Die Zeiten sind bei mir hoffentlich vergangenheit, in denen ich nicht exceptionsicheren Code schreibe, zumindest die um die Einhaltung der Basisgarantie bemühe ich mich. Schon das ist machmal frickelig.


Bearbeitung:

Hm, auch der Zuweisungsoperator von ao ist sicher:

Zitat von ao:


C++:
Test & operator=(int nValue) {*myint = nValue; return *this;}





Zitat von virtual:

sorry, war geytern schon spät:


Offensichtlich...


--
Wer früher stirbt ist länger tot.

Dieser Post wurde am 04.11.2004 um 07:57 Uhr von (un)wissender editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: