<?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[Problem mit Copy Constructor - wie lösen?]]></title><description><![CDATA[<p>hi leute,</p>
<p>ich hab ein problem mit einer implementierung und sehe grade nicht wirklich eine möglichkeit, da drum rum zu kommen. kurzes minimalbeispiel:</p>
<pre><code class="language-cpp">class C1 {
public:
  virtual C1 f() {return C1();};
  virtual int getI() {return -1;};
};

class C2 : public C1 {
public:
  int i;

  C1 f() {/* viel code*/};
  int getI() {return i;};
};
</code></pre>
<p>jetzt ist das problem:</p>
<pre><code class="language-cpp">C2 a;
a.i = 2;
C1 b = a.f();
b.getI(); // nicht 2, wird der copy constructor nicht aufgerufen?
</code></pre>
<p>kann mir jemand helfen? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/topic/243007/problem-mit-copy-constructor-wie-lösen</link><generator>RSS for Node</generator><lastBuildDate>Sun, 20 Sep 2026 15:10:31 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/243007.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 10 Jun 2009 22:06:32 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Problem mit Copy Constructor - wie lösen? on Wed, 10 Jun 2009 22:06:32 GMT]]></title><description><![CDATA[<p>hi leute,</p>
<p>ich hab ein problem mit einer implementierung und sehe grade nicht wirklich eine möglichkeit, da drum rum zu kommen. kurzes minimalbeispiel:</p>
<pre><code class="language-cpp">class C1 {
public:
  virtual C1 f() {return C1();};
  virtual int getI() {return -1;};
};

class C2 : public C1 {
public:
  int i;

  C1 f() {/* viel code*/};
  int getI() {return i;};
};
</code></pre>
<p>jetzt ist das problem:</p>
<pre><code class="language-cpp">C2 a;
a.i = 2;
C1 b = a.f();
b.getI(); // nicht 2, wird der copy constructor nicht aufgerufen?
</code></pre>
<p>kann mir jemand helfen? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1724855</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1724855</guid><dc:creator><![CDATA[luke-r2d2]]></dc:creator><pubDate>Wed, 10 Jun 2009 22:06:32 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit Copy Constructor - wie lösen? on Wed, 10 Jun 2009 22:09:00 GMT]]></title><description><![CDATA[<p>Du verlierst die Eigenschaften der Polymorphie, wenn es sich um reine Objekte (also Kopien) handelt. Nimm stattdessen Zeiger oder Referenzen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1724856</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1724856</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Wed, 10 Jun 2009 22:09:00 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit Copy Constructor - wie lösen? on Wed, 10 Jun 2009 22:09:41 GMT]]></title><description><![CDATA[<p>Jaaah, da wollte ich gerade rum kommen... Aber wahrscheinlich hast du Recht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1724857</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1724857</guid><dc:creator><![CDATA[luke-r2d2]]></dc:creator><pubDate>Wed, 10 Jun 2009 22:09:41 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit Copy Constructor - wie lösen? on Wed, 10 Jun 2009 22:15:12 GMT]]></title><description><![CDATA[<p>Hm. Um was für eine Funktion handelt es sich bei <code>f</code> im Originalbeispiel? Musst du wirklich eine neue Instanz der Klasse zurückgeben? Und diese sollte polymorphes Verhalten aufweisen?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1724859</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1724859</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Wed, 10 Jun 2009 22:15:12 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit Copy Constructor - wie lösen? on Wed, 10 Jun 2009 22:16:55 GMT]]></title><description><![CDATA[<p>Im Original ist C1 eine Basisklasse für Trajektorien, also eine Approximation für mathematische Funktionen. C2 ist dann eine Implementierung (Polynom / Spline). f() entspricht der Ableitung dieser Trajektorie.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1724860</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1724860</guid><dc:creator><![CDATA[luke-r2d2]]></dc:creator><pubDate>Wed, 10 Jun 2009 22:16:55 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit Copy Constructor - wie lösen? on Wed, 10 Jun 2009 22:28:17 GMT]]></title><description><![CDATA[<p>Okay. Grundsätzlich musst du wohl Speicher dynamisch anfordern, da ja im Voraus nicht klar ist, was <code>f()</code> für einen (dynamischen) Typen zurückgibt.</p>
<pre><code class="language-cpp">C1* C1::f() const // &lt;- verändert Methode etwas an this?
{
    C1* NewC;
    if (...)
        NewC = new C2(...);
    else
        NewC = new C3(...);
    return NewC;
}
</code></pre>
<p>So hast du allerdings noch das Problem, wer den Speicher freigibt. Du kannst zum Beispiel eine analoge Freigabefunktion benutzen (eventuell wären freie Funktionen, auch für die Objekterstellung, die bessere Wahl):</p>
<pre><code class="language-cpp">C1* CreateC() const;
void DestroyC(C1* c) const;
</code></pre>
<p>Oder du nutzt gleich C++'s Möglichkeiten der RAII und gibst einen Smart Pointer zurück, zum Beispiel <code>boost::shared_ptr</code> ( <code>std::tr1::shared_ptr</code> ), wobei hier eigentlich <code>std::auto_ptr</code> reichen sollte. Wenn du diesen nicht kennst, schau mal auf <a href="http://www.cplusplus.com" rel="nofollow">www.cplusplus.com</a> nach.</p>
<pre><code class="language-cpp">std::auto_ptr&lt;C1&gt; f() const;
</code></pre>
<p>Achja, vergiss übrigens den virtuellen Destruktor nicht, sonst werden deine polymorphen Objekte nicht richtig zerstört.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1724864</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1724864</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Wed, 10 Jun 2009 22:28:17 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit Copy Constructor - wie lösen? on Wed, 10 Jun 2009 22:33:00 GMT]]></title><description><![CDATA[<p>Nein, die Methode macht an this nichts.Freie Funktionen sind eher unschön, wahrscheinlich werde ich es einfach mal mit den Pointern probieren... Muss ich mich halt sauber ums freigeben kümmern, wofür gibts valgrind <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<p>Virtueller Destructor war natürlich drinnen...</p>
<p>Den auto_ptr kannte ich noch nicht, das ist klasse! Vielen Dank, muss mich da aber erst mal an den Gedanken gewöhnen, das ist ja schon fast Java <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1724866</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1724866</guid><dc:creator><![CDATA[luke-r2d2]]></dc:creator><pubDate>Wed, 10 Jun 2009 22:33:00 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit Copy Constructor - wie lösen? on Wed, 10 Jun 2009 22:54:58 GMT]]></title><description><![CDATA[<p>luke-r2d2 schrieb:</p>
<blockquote>
<p>wahrscheinlich werde ich es einfach mal mit den Pointern probieren... Muss ich mich halt sauber ums freigeben kümmern, wofür gibts valgrind <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
</blockquote>
<p>Bei Smart Pointers wie <code>std::auto_ptr</code> musst du dich eben <strong>nicht</strong> ums Freigeben kümmern. Und der Overhead sollte vertretbar sein...</p>
<p>luke-r2d2 schrieb:</p>
<blockquote>
<p>Freie Funktionen sind eher unschön</p>
</blockquote>
<p>Das würde ich in C++ nicht sagen. Geh mal rüber zu den C'lern, die werden dich umbringen. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
<p>Nein, im Ernst. Ich finde, wenn eine Funktion keinen direkten Zugriff auf die Member braucht oder aus sonstigen Gründen auch genauso gut ausserhalb der Klasse stehen kann, in diesem Falle eine globale Funktion besser und schöner. Es bringt einem nichts, sie in der Klasse zu haben. Nur weil das von gewissen Leuten nicht als &quot;objektorientiert&quot; angesehen wird, ist für mich kein Grund. Allein dass man die Funktion in die Klasse steckt, macht das Ganze nicht objektorientierter, geschweige denn eleganter.</p>
<p>Freie Funktionen können genauso gut zur Schnittstelle einer Klasse gehören. Beispiel wären bei einer Vektorklasse Funktionen zur Länge. Ich finde es auch syntaktisch schöner, zu schreiben:</p>
<pre><code class="language-cpp">float Length = Norm(Vector1 + 2 * Vector2);
</code></pre>
<p>schöner als:</p>
<pre><code class="language-cpp">float Length = (Vector1 + 2 * Vector2).Norm();
</code></pre>
<p>Und nach Java richten würde ich mich in C++ erst recht nicht. Dann hätte man nämlich</p>
<pre><code class="language-cpp">float length = (vector1.add(vector2.mult(2))).norm();
</code></pre>
<p>:p</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1724870</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1724870</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Wed, 10 Jun 2009 22:54:58 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit Copy Constructor - wie lösen? on Wed, 10 Jun 2009 22:57:28 GMT]]></title><description><![CDATA[<p>Hmja, okay <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<p>Den Overhead von den smart pointers kann ich noch nicht einschätzen... Kann nur sagen, dass das Programm mal ein paar Tage auf nem Superrechner laufen wird, da machen auch Kleinigkeiten viel aus <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /> Wobei ich nicht denke, dass das selber Freigeben ein so großes Problem sein sollte, ich benutze das zum Glück nur selten.</p>
<p>Freie Funktionen können schöner sein - müssen aber nicht. Ich bevorzuge in dem Fall</p>
<pre><code class="language-cpp">traj-&gt;getSubTraj(i, n)-&gt;derivative()-&gt;derivative()-&gt;calculatePoint(t)
</code></pre>
<p>(Freigabe erfolgt in traj, ich speichere jetzt einfach die Ableitungen direkt ab - spart auch Rechenzeit)</p>
<p>vor irgendwelchen freien Funktionen. Ich denke, das ist Einstellungssache - ein weiterer Vorteil ist, dass ich z.B. verschiedene derivative() Funktionen in meinem Programm habe, und dann wäre ein derivativeSpline(), derivativeVector(), etc eher unschön. Mit Klassen ist das halt auch sortiert...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1724874</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1724874</guid><dc:creator><![CDATA[luke-r2d2]]></dc:creator><pubDate>Wed, 10 Jun 2009 22:57:28 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit Copy Constructor - wie lösen? on Wed, 10 Jun 2009 23:09:31 GMT]]></title><description><![CDATA[<p>Ja, es kommt ganz auf den Anwendungsfall drauf an. Nur würde ich mich hüten, generell etwas gegen freie Funktionen zu haben. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<p>Zu dem Selber Freigeben: Mach es wenn schon so, dass eine Funktion im gleichen Scope für die Freigabe verantwortlich ist. Und gewöhn dir besser nicht an, sowas zu machen:</p>
<pre><code class="language-cpp">C* t = bla.CreateC();
delete t;
</code></pre>
<p>Also direkt freigeben. Denn damit machst du dich von der Implementierung der Anforderungsfunktion abhängig. Was, wenn <code>CreateC()</code> nicht mehr mit <code>new</code> anfordert? Oder wenn es etwas zusätzlich macht, das beim Freigeben wieder rückgängig gemacht werden soll? Auch wenn es hier vielleicht nicht so relevant ist, würde ich trotzdem schon darauf achten, diesbezüglich konsistent zu bleiben und eine entsprechende Freigabefunktion in der Klasse anzubieten. Du verlierst dadurch nichts.</p>
<p>Und was Smart Pointers angeht: Die können sich schnell einmal lohnen. Gerade wenn man eine Funktion über mehrere Wege verlassen kann (z.B. auch durch Exceptions), muss man enorm viel Code schreiben, um in jedem Fall für eine Freigabe zu sorgen. Bei Smart Pointers hat man das gratis - ein <code>auto_ptr</code> gibt den Speicher frei, wenn er selber zerstört wird - also normalerweise beim Verlassen des Scopes. Und <code>auto_ptr</code> ist ein verhältnismässig leichtgewichtiger Smart Pointer. Ich weiss nicht, ob der Overhead überhaupt spürbar ist. Und falls doch, lieber keine Memory Leaks als ein 0.0001% langsameres Programm. <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/1724879</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1724879</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Wed, 10 Jun 2009 23:09:31 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit Copy Constructor - wie lösen? on Wed, 10 Jun 2009 23:27:23 GMT]]></title><description><![CDATA[<p>Hmm, okay, danke auf jeden Fall für nen Tipp mit den smart pointers <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /> Muss ich mir wirklich mal genauer anschaun, bzw verstehen, was genau ich damit machen darf <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61b.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_tongue"
      title=":P"
      alt="😛"
    /></p>
<p>Und mit der eigenen Freigabefunktion - das mein ich ja <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /> Also den Pointer in der Klasse abspeichern und beim Zerstören mit vernichten <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61b.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_tongue"
      title=":P"
      alt="😛"
    /> (oder eben über Funktionen)...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1724888</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1724888</guid><dc:creator><![CDATA[luke-r2d2]]></dc:creator><pubDate>Wed, 10 Jun 2009 23:27:23 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit Copy Constructor - wie lösen? on Thu, 11 Jun 2009 13:03:27 GMT]]></title><description><![CDATA[<p>luke-r2d2 schrieb:</p>
<blockquote>
<p>Und mit der eigenen Freigabefunktion - das mein ich ja <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /> Also den Pointer in der Klasse abspeichern und beim Zerstören mit vernichten <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61b.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_tongue"
      title=":P"
      alt="😛"
    /> (oder eben über Funktionen)...</p>
</blockquote>
<p>Dann meinst du aber doch was anderes. Wieso soll der Pointer in der Klasse abgespeichert werden? Der ist ja unabhängig von der Lebenszeit des Objekts, das ihn erstellt. Zumindest ist es gefährlich, einen Pointer anzufordern, von dem man nicht weiss, wann er freigegeben wird. Damit hast du wieder die erwähnte Inkonsistenz.</p>
<p>Was ich meinte, ist, dass derjenige, der den Speicher anfordert, auch wieder für dessen Freigabe verantwortlich sein sollte. Also in deinem Beispiel der Aufrufer der Trajektorien-Erstellungsfunktion und eben <em>nicht</em> die Klasse, die die Erstellungsfunktion bereitstellt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1725031</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1725031</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Thu, 11 Jun 2009 13:03:27 GMT</pubDate></item><item><title><![CDATA[Reply to Problem mit Copy Constructor - wie lösen? on Thu, 11 Jun 2009 14:03:08 GMT]]></title><description><![CDATA[<p>Hmm, es ist aber sinnvoll, in einer Trajektorie die Ableitung abzuspeichern, wenn man die öfter braucht <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1725057</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1725057</guid><dc:creator><![CDATA[luke-r2d2]]></dc:creator><pubDate>Thu, 11 Jun 2009 14:03:08 GMT</pubDate></item></channel></rss>