<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Kopierkonstruktor nur bei Variablen die sich auf dem Heap befinden nötig]]></title><description><![CDATA[<p>Ich hab da grad ein Beispiel aus meinem Buch (das Beispiel geht nicht direkt über Kopierkonstruktoren) das ich nicht verstehe, bzw. ich finde eine Codestelle Sinnlos.<br />
Einen Kopierkonstruktor benötigt man doch nur wenn man in einer Klasse z.B. eine Variable namens &quot;int *itsAge&quot; hat, also einen Zeiger auf dem ein Speicherbereich auf dem Heap reserviert wird. Und den Kopierkonstruktor hat man nur dazu, wenn man das Objekt in der sich &quot;int *itsAge&quot; befindet in eine anderes Objekt überträgt und sich die Adresse von &quot;int *itsAge&quot; nicht verändert hat. Das würde also heißen, das nun beide &quot;int *itsAge&quot; Zeiger auf die gleiche Speicherstelle verweisen. Das is natürlich blöd und führt früher oder später zu ungereimtheiten oder einem Error (wenn das eine Objekt vll. den Zeiger schon deleted hat, und in dem anderen der Zeiger(Speicherbereich) eigentlich noch vorhanden sein sollte).<br />
So aber bei einer ganz normalen Variable &quot;int itsAge&quot; braucht man doch keinen Kopierkonstruktor etc... weil die verwaltet doch der PC\Compiler (?) selbst oder so?<br />
Und dann wären wir hier auch schon mal bei dem (langen) Beispiel, wo mich eigentlich nur 2 Codestellen interessieren:</p>
<pre><code class="language-cpp">// Listing 17.4 Virtueller Kopierkonstruktor

 #include &lt;iostream&gt;

 class Mammal

 {

 public:

     Mammal():itsAge(1) { std::cout &lt;&lt; &quot;Mammal-Konstruktor...\n&quot;; }

     virtual ~Mammal() { std::cout &lt;&lt; &quot;Mammal-Destruktor...\n&quot;; }

     Mammal (const Mammal &amp; rhs);

     virtual void Speak() const { std::cout &lt;&lt; &quot;Mammal gib Laut!\n&quot;; }

     virtual Mammal* Clone() { return new Mammal(*this); }

     int GetAge()const { return itsAge; }

 protected:

     int itsAge; //&lt;-- HIER ganz normale Variable, kein Zeiger!

 };

 Mammal::Mammal (const Mammal &amp; rhs):itsAge(rhs.GetAge()) /*Was soll das hier? Muss man nun auch bei ganz normalen Variablen schon Kopierkonstruktoren einsetzen? Das wäre mit aber ganze neu, und verwirrt mich deshalb nun so sehr. Ist das jetzt echt normal das man bei ganz normalen Variablen (also bei &quot;nicht-Zeigern&quot;) schon nen Kopierkonstruktor braucht? Ich hab immer gedacht nur bei Zeigern aufm Heap! Mhh?*/ 

 {

     std::cout &lt;&lt; &quot;Mammal-Kopierkonstruktor...\n&quot;;

 }

 class Dog : public Mammal

 {

 public:

     Dog() { std::cout &lt;&lt; &quot;Dog-Konstruktor...\n&quot;; }

     virtual ~Dog() { std::cout &lt;&lt; &quot;Dog-Destruktor...\n&quot;; }

     Dog (const Dog &amp; rhs);

     void Speak()const { std::cout &lt;&lt; &quot;Wuff!\n&quot;; }

     virtual Mammal* Clone() { return new Dog(*this); }

 };

 Dog::Dog(const Dog &amp; rhs):

 Mammal(rhs)

 {

     std::cout &lt;&lt; &quot;Dog-Kopierkonstruktor...\n&quot;;

 }

 class Cat : public Mammal

 {

 public:

     Cat() { std::cout &lt;&lt; &quot;Cat-Konstruktor...\n&quot;; }

     virtual ~Cat() { std::cout &lt;&lt; &quot;Cat-Destruktor...\n&quot;; }

     Cat (const Cat &amp;);

     void Speak()const { std::cout &lt;&lt; &quot;Miau!\n&quot;; }

     virtual Mammal* Clone() { return new Cat(*this); }

 };

 Cat::Cat(const Cat &amp; rhs):

 Mammal(rhs)

 {

     std::cout &lt;&lt; &quot;Cat-Kopierkonstruktor...\n&quot;;

 }

 enum ANIMALS { MAMMAL, DOG, CAT};

 const int NumAnimalTypes = 3;

 int main()

 {

     Mammal *theArray[NumAnimalTypes];

     Mammal* ptr;

     int choice,i;

     for (i = 0; i&lt;NumAnimalTypes; i++)

     {

         std::cout &lt;&lt; &quot;(1)Hund (2)Katze (3)Säugetier: &quot;;

         std::cin &gt;&gt; choice;

         switch (choice)

         {

         case DOG:

             ptr = new Dog;

             break;

         case CAT:

             ptr = new Cat;

             break;

         default:

             ptr = new Mammal;

             break;

         }

         theArray[i] = ptr;

     }

     Mammal *OtherArray[NumAnimalTypes];

     for (i=0;i&lt;NumAnimalTypes;i++)

     {

         theArray[i]-&gt;Speak();

         OtherArray[i] = theArray[i]-&gt;Clone();

     }

     for (i=0;i&lt;NumAnimalTypes;i++)

         OtherArray[i]-&gt;Speak();

     return 0;

 }
</code></pre>
<p>Bitte klärt mich auf. Dankeschön schon mal im Voraus.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/175477/kopierkonstruktor-nur-bei-variablen-die-sich-auf-dem-heap-befinden-nötig</link><generator>RSS for Node</generator><lastBuildDate>Sat, 19 Sep 2026 03:13:11 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/175477.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 10 Mar 2007 21:49:17 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Kopierkonstruktor nur bei Variablen die sich auf dem Heap befinden nötig on Sat, 10 Mar 2007 21:49:59 GMT]]></title><description><![CDATA[<p>Ich hab da grad ein Beispiel aus meinem Buch (das Beispiel geht nicht direkt über Kopierkonstruktoren) das ich nicht verstehe, bzw. ich finde eine Codestelle Sinnlos.<br />
Einen Kopierkonstruktor benötigt man doch nur wenn man in einer Klasse z.B. eine Variable namens &quot;int *itsAge&quot; hat, also einen Zeiger auf dem ein Speicherbereich auf dem Heap reserviert wird. Und den Kopierkonstruktor hat man nur dazu, wenn man das Objekt in der sich &quot;int *itsAge&quot; befindet in eine anderes Objekt überträgt und sich die Adresse von &quot;int *itsAge&quot; nicht verändert hat. Das würde also heißen, das nun beide &quot;int *itsAge&quot; Zeiger auf die gleiche Speicherstelle verweisen. Das is natürlich blöd und führt früher oder später zu ungereimtheiten oder einem Error (wenn das eine Objekt vll. den Zeiger schon deleted hat, und in dem anderen der Zeiger(Speicherbereich) eigentlich noch vorhanden sein sollte).<br />
So aber bei einer ganz normalen Variable &quot;int itsAge&quot; braucht man doch keinen Kopierkonstruktor etc... weil die verwaltet doch der PC\Compiler (?) selbst oder so?<br />
Und dann wären wir hier auch schon mal bei dem (langen) Beispiel, wo mich eigentlich nur 2 Codestellen interessieren:</p>
<pre><code class="language-cpp">// Listing 17.4 Virtueller Kopierkonstruktor

 #include &lt;iostream&gt;

 class Mammal

 {

 public:

     Mammal():itsAge(1) { std::cout &lt;&lt; &quot;Mammal-Konstruktor...\n&quot;; }

     virtual ~Mammal() { std::cout &lt;&lt; &quot;Mammal-Destruktor...\n&quot;; }

     Mammal (const Mammal &amp; rhs);

     virtual void Speak() const { std::cout &lt;&lt; &quot;Mammal gib Laut!\n&quot;; }

     virtual Mammal* Clone() { return new Mammal(*this); }

     int GetAge()const { return itsAge; }

 protected:

     int itsAge; //&lt;-- HIER ganz normale Variable, kein Zeiger!

 };

 Mammal::Mammal (const Mammal &amp; rhs):itsAge(rhs.GetAge()) /*Was soll das hier? Muss man nun auch bei ganz normalen Variablen schon Kopierkonstruktoren einsetzen? Das wäre mit aber ganze neu, und verwirrt mich deshalb nun so sehr. Ist das jetzt echt normal das man bei ganz normalen Variablen (also bei &quot;nicht-Zeigern&quot;) schon nen Kopierkonstruktor braucht? Ich hab immer gedacht nur bei Zeigern aufm Heap! Mhh?*/ 

 {

     std::cout &lt;&lt; &quot;Mammal-Kopierkonstruktor...\n&quot;;

 }

 class Dog : public Mammal

 {

 public:

     Dog() { std::cout &lt;&lt; &quot;Dog-Konstruktor...\n&quot;; }

     virtual ~Dog() { std::cout &lt;&lt; &quot;Dog-Destruktor...\n&quot;; }

     Dog (const Dog &amp; rhs);

     void Speak()const { std::cout &lt;&lt; &quot;Wuff!\n&quot;; }

     virtual Mammal* Clone() { return new Dog(*this); }

 };

 Dog::Dog(const Dog &amp; rhs):

 Mammal(rhs)

 {

     std::cout &lt;&lt; &quot;Dog-Kopierkonstruktor...\n&quot;;

 }

 class Cat : public Mammal

 {

 public:

     Cat() { std::cout &lt;&lt; &quot;Cat-Konstruktor...\n&quot;; }

     virtual ~Cat() { std::cout &lt;&lt; &quot;Cat-Destruktor...\n&quot;; }

     Cat (const Cat &amp;);

     void Speak()const { std::cout &lt;&lt; &quot;Miau!\n&quot;; }

     virtual Mammal* Clone() { return new Cat(*this); }

 };

 Cat::Cat(const Cat &amp; rhs):

 Mammal(rhs)

 {

     std::cout &lt;&lt; &quot;Cat-Kopierkonstruktor...\n&quot;;

 }

 enum ANIMALS { MAMMAL, DOG, CAT};

 const int NumAnimalTypes = 3;

 int main()

 {

     Mammal *theArray[NumAnimalTypes];

     Mammal* ptr;

     int choice,i;

     for (i = 0; i&lt;NumAnimalTypes; i++)

     {

         std::cout &lt;&lt; &quot;(1)Hund (2)Katze (3)Säugetier: &quot;;

         std::cin &gt;&gt; choice;

         switch (choice)

         {

         case DOG:

             ptr = new Dog;

             break;

         case CAT:

             ptr = new Cat;

             break;

         default:

             ptr = new Mammal;

             break;

         }

         theArray[i] = ptr;

     }

     Mammal *OtherArray[NumAnimalTypes];

     for (i=0;i&lt;NumAnimalTypes;i++)

     {

         theArray[i]-&gt;Speak();

         OtherArray[i] = theArray[i]-&gt;Clone();

     }

     for (i=0;i&lt;NumAnimalTypes;i++)

         OtherArray[i]-&gt;Speak();

     return 0;

 }
</code></pre>
<p>Bitte klärt mich auf. Dankeschön schon mal im Voraus.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1243128</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1243128</guid><dc:creator><![CDATA[Stromberg]]></dc:creator><pubDate>Sat, 10 Mar 2007 21:49:59 GMT</pubDate></item><item><title><![CDATA[Reply to Kopierkonstruktor nur bei Variablen die sich auf dem Heap befinden nötig on Sat, 10 Mar 2007 22:04:20 GMT]]></title><description><![CDATA[<p>Du hast es genau falsch verstanden. Wenn zwei Zeiger auf dasselbe Objekt zeigen, braucht man eben keinen Kopierkonstruktor, es wird ja nichts kopiert (außer einem Zeiger).</p>
<p>Wenn man hingegen eine *Kopie* eines Objekts erzeugen will, dann wird der Kopierkonstruktor aufgerufen. Also hier:</p>
<pre><code class="language-cpp">class Foo {};

// ...

Foo x;
Foo y = x; // Hier wird der Kopierkonstruktor von 'Foo' aufgerufen.

Foo* z = &amp;x; // Hier nicht.
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1243133</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1243133</guid><dc:creator><![CDATA[Konrad Rudolph]]></dc:creator><pubDate>Sat, 10 Mar 2007 22:04:20 GMT</pubDate></item><item><title><![CDATA[Reply to Kopierkonstruktor nur bei Variablen die sich auf dem Heap befinden nötig on Sat, 10 Mar 2007 22:14:28 GMT]]></title><description><![CDATA[<p>Ja okay, aber ist das hier nun unsinnig oder ist das wichtig? [Zeile 35]</p>
<pre><code class="language-cpp">...
Mammal::Mammal (const Mammal &amp; rhs):itsAge(rhs.GetAge())
...
</code></pre>
<p>Weil &quot;itsAge&quot; ist doch gar kein Zeiger.<br />
Dankeschön schon mal im Voraus.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1243135</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1243135</guid><dc:creator><![CDATA[Stromberg]]></dc:creator><pubDate>Sat, 10 Mar 2007 22:14:28 GMT</pubDate></item><item><title><![CDATA[Reply to Kopierkonstruktor nur bei Variablen die sich auf dem Heap befinden nötig on Sat, 10 Mar 2007 22:20:12 GMT]]></title><description><![CDATA[<p>Stromberg schrieb:</p>
<blockquote>
<p>Ja okay, aber ist das hier nun unsinnig oder ist das wichtig? [Zeile 35]</p>
<pre><code class="language-cpp">...
Mammal::Mammal (const Mammal &amp; rhs):itsAge(rhs.GetAge())
...
</code></pre>
<p>Weil &quot;itsAge&quot; ist doch gar kein Zeiger.</p>
</blockquote>
<p>Ja, wir wollen den Wert doch auch *kopieren*! Wieso sollte das denn ein Zeiger sein?</p>
<p>Also, ist richtig so. Wir kopieren das Alter der alten Instanz in das der neuen Instanz.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1243138</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1243138</guid><dc:creator><![CDATA[Konrad Rudolph]]></dc:creator><pubDate>Sat, 10 Mar 2007 22:20:12 GMT</pubDate></item><item><title><![CDATA[Reply to Kopierkonstruktor nur bei Variablen die sich auf dem Heap befinden nötig on Sat, 10 Mar 2007 22:49:17 GMT]]></title><description><![CDATA[<p>Ja aber es gibt doch auch einen &quot;Standardkopierkonstruktor&quot;, somit ist doch</p>
<pre><code class="language-cpp">...
Mammal::Mammal (const Mammal &amp; rhs):itsAge(rhs.GetAge())
...
</code></pre>
<p>nicht falsch, aber unnötig?<br />
In meinem Buch steht:</p>
<blockquote>
<p>Der Standardkopierkonstruktor kopiert einfach jede Elementvariable von dem als Paramter übergebenem Objekt in die Elementvariablen des neuen Objekts. Man spricht hier von einer elementweisen (oder flachen) Kopie. Obwohl das bei den meisetn Elementvariablen durchaus funktioniert, klappt das bei Elementvariablen, die Zeiger auf Objekte im Heap sind, schon nicht mehr wie beabsichtigt.<br />
Eine flache oder elementweise Kopier kopiert die genauen Werte der Elementvariablen des einen Objekts in ein anderes Objekt. Zeiger in beiden Objekten verweisen letztendlich auf denselben Speicher. eine tiefe Kopie überträgt andererseits die auf dem Heap reservierten Werte in neu zugewiesenen Speicher.</p>
</blockquote>
<p>Das hab ich mit den andauerden &quot;Zeigern&quot; gemeint. Weißt was ich mein? Soll ich in Zukunft trotzdem einfach immer alle Elementvariablen in den Kopierkonstruktor mitreinschreiben? Oder jetzt doch nur die Zeiger die auf Speicher auf dem Heap verweisen? Oder doch alle? Dankeschön schon mal im Voraus.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1243145</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1243145</guid><dc:creator><![CDATA[Stromberg]]></dc:creator><pubDate>Sat, 10 Mar 2007 22:49:17 GMT</pubDate></item><item><title><![CDATA[Reply to Kopierkonstruktor nur bei Variablen die sich auf dem Heap befinden nötig on Sat, 10 Mar 2007 22:58:03 GMT]]></title><description><![CDATA[<p>Stromberg schrieb:</p>
<blockquote>
<p>Ja aber es gibt doch auch einen &quot;Standardkopierkonstruktor&quot;, somit ist doch</p>
<pre><code class="language-cpp">...
Mammal::Mammal (const Mammal &amp; rhs):itsAge(rhs.GetAge())
...
</code></pre>
<p>nicht falsch, aber unnötig?</p>
</blockquote>
<p>Ach so. Jetzt verstehe ich. Ja, Du hast recht, er ist natürlich in diesem Fall unnötig und kann getrost weggelassen werden. Und Du hast recht, ein Fall, in dem er nötig ist, tritt auf, wenn man sich um die manuelle Verwaltung von Heapspeicher kümmern muss.</p>
<p>Sorry, habe einfach zu kurz gedacht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1243147</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1243147</guid><dc:creator><![CDATA[Konrad Rudolph]]></dc:creator><pubDate>Sat, 10 Mar 2007 22:58:03 GMT</pubDate></item><item><title><![CDATA[Reply to Kopierkonstruktor nur bei Variablen die sich auf dem Heap befinden nötig on Sun, 11 Mar 2007 00:19:06 GMT]]></title><description><![CDATA[<p>Das Beispiel sieht mir nicht nach einer Stilrichtlinie zu Kopierkonstruktoren aus. Ich mach jedenfalls nie Ausgaben der Form &quot;Ich werde gerade kopiert&quot; <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1243161</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1243161</guid><dc:creator><![CDATA[Bashar]]></dc:creator><pubDate>Sun, 11 Mar 2007 00:19:06 GMT</pubDate></item><item><title><![CDATA[Reply to Kopierkonstruktor nur bei Variablen die sich auf dem Heap befinden nötig on Sun, 11 Mar 2007 09:09:29 GMT]]></title><description><![CDATA[<p>ich denke, das ist hier nur ein zwischenschritt des autors, um zu zeigen, wann der kopierkonstruktor arbeitet.<br />
interessant sind hier sicher die übergabe per value, und die erkenntnis, was dann alles gepusht und gepopt wird.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1243211</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1243211</guid><dc:creator><![CDATA[elise]]></dc:creator><pubDate>Sun, 11 Mar 2007 09:09:29 GMT</pubDate></item></channel></rss>