<?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[Fehler im Konstruktor -&amp;gt; sinnvolle Reaktion?]]></title><description><![CDATA[<p>Ahoi...</p>
<p>Wenn man im Konstruktor feststellt, dass die Klasse aufgrund fehlerhafter / falsche Parameter nicht erzeugt werden kann, wie reagiert man dann darauf sinnvoll? Soweit ich gelesen habe, sollte man Exceptions im Konstruktor vermeiden...</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/247457/fehler-im-konstruktor-gt-sinnvolle-reaktion</link><generator>RSS for Node</generator><lastBuildDate>Thu, 17 Sep 2026 13:13:38 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/247457.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 11 Aug 2009 11:52:55 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Fehler im Konstruktor -&amp;gt; sinnvolle Reaktion? on Tue, 11 Aug 2009 11:52:55 GMT]]></title><description><![CDATA[<p>Ahoi...</p>
<p>Wenn man im Konstruktor feststellt, dass die Klasse aufgrund fehlerhafter / falsche Parameter nicht erzeugt werden kann, wie reagiert man dann darauf sinnvoll? Soweit ich gelesen habe, sollte man Exceptions im Konstruktor vermeiden...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1758806</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1758806</guid><dc:creator><![CDATA[wyfrn]]></dc:creator><pubDate>Tue, 11 Aug 2009 11:52:55 GMT</pubDate></item><item><title><![CDATA[Reply to Fehler im Konstruktor -&amp;gt; sinnvolle Reaktion? on Tue, 11 Aug 2009 11:55:49 GMT]]></title><description><![CDATA[<p>Exceptions im Konstruktor sind kein Problem. Die Subobjekte werden dann in der umgekehrten Reihenfolge wie sie erzeugt wurden wieder zerstört.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1758809</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1758809</guid><dc:creator><![CDATA[Ryuzaki]]></dc:creator><pubDate>Tue, 11 Aug 2009 11:55:49 GMT</pubDate></item><item><title><![CDATA[Reply to Fehler im Konstruktor -&amp;gt; sinnvolle Reaktion? on Tue, 11 Aug 2009 12:30:36 GMT]]></title><description><![CDATA[<p>Na so:</p>
<pre><code class="language-cpp">class Test {
  public:
  Test(const char *name) {
    if(name == NULL)
      initialized = false;
    else
      initialized = true;
    this-&gt;name = name;
  }

  bool is_initialized() {
     return initialized;
  }

  private:
    boost initialized;
    std::string name;
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1758834</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1758834</guid><dc:creator><![CDATA[SCNR]]></dc:creator><pubDate>Tue, 11 Aug 2009 12:30:36 GMT</pubDate></item><item><title><![CDATA[Reply to Fehler im Konstruktor -&amp;gt; sinnvolle Reaktion? on Tue, 11 Aug 2009 12:37:46 GMT]]></title><description><![CDATA[<p>Exceptions sollte man nur im Destruktor nicht werfen oder dann im Destruktor fangen, aber nie aus dem Destruktor raus. Im Konstruktor ist es kein Problem, vor allem wenn man sich an RAII gehalten hat.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1758839</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1758839</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Tue, 11 Aug 2009 12:37:46 GMT</pubDate></item><item><title><![CDATA[Reply to Fehler im Konstruktor -&amp;gt; sinnvolle Reaktion? on Tue, 11 Aug 2009 12:41:17 GMT]]></title><description><![CDATA[<p>Ryuzaki schrieb:</p>
<blockquote>
<p>Exceptions im Konstruktor sind kein Problem. Die Subobjekte werden dann in der umgekehrten Reihenfolge wie sie erzeugt wurden wieder zerstört.</p>
</blockquote>
<p>Wobei man zwischen dynamischer Allokation und statischer Unterscheiden sollte.</p>
<p>Nehmen wir in den folgenden Fall an das a und b Zeiger auf A sind:</p>
<pre><code class="language-cpp">Bar::Bar()
:   a(new A()),
    b(new A())
{
}
</code></pre>
<p>Wenn nun bei dem zweiten new eine Exception auftritt wird der Speicher von a nicht freigegeben. Sind a und b statt dessen Smartpointer (wie z.b. scoped_ptr oder shared_ptr von Boost oder TR1), wird der Speicher freigegeben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1758841</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1758841</guid><dc:creator><![CDATA[asc]]></dc:creator><pubDate>Tue, 11 Aug 2009 12:41:17 GMT</pubDate></item><item><title><![CDATA[Reply to Fehler im Konstruktor -&amp;gt; sinnvolle Reaktion? on Tue, 11 Aug 2009 13:07:50 GMT]]></title><description><![CDATA[<p>asc schrieb:</p>
<blockquote>
<p>Wenn nun bei dem zweiten new eine Exception auftritt wird der Speicher von a nicht freigegeben.</p>
</blockquote>
<p>Das ist eigentlich nicht wahr, was nur illustriert, wie wichtig es ist, sich genau auszudrücken.<br />
Der <em>Speicher von a</em>, also der Speicher, den das Objekt a einnimmt, wird sehr wohl freigegeben.<br />
Der Speicher, der beim ersten new reserviert wurde, und auf den a zeigt, hingegen nicht.<br />
Nicht klar zu unterscheiden zwischen dem dynamisch angeforderten Speicher und dem Zeigerobjekt, ist immerhin ein typischer Anfängerfehler, hat aber nichts speziell mit Konstruktoren und Exceptions zu tun.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1758853</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1758853</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Tue, 11 Aug 2009 13:07:50 GMT</pubDate></item><item><title><![CDATA[Reply to Fehler im Konstruktor -&amp;gt; sinnvolle Reaktion? on Tue, 11 Aug 2009 13:22:40 GMT]]></title><description><![CDATA[<p>SCNR schrieb:</p>
<blockquote>
<p>Na so:</p>
<pre><code class="language-cpp">class Test {
  public:
  Test(const char *name) {
    if(name == NULL)
      initialized = false;
    else
      initialized = true;
    this-&gt;name = name;
  }

  bool is_initialized() {
     return initialized;
  }

  private:
    boost initialized;
    std::string name;
};
</code></pre>
</blockquote>
<p>Ist daran etwas schlecht? Ich mache das auch immer so.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1758865</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1758865</guid><dc:creator><![CDATA[Manfred T.]]></dc:creator><pubDate>Tue, 11 Aug 2009 13:22:40 GMT</pubDate></item><item><title><![CDATA[Reply to Fehler im Konstruktor -&amp;gt; sinnvolle Reaktion? on Tue, 11 Aug 2009 13:49:37 GMT]]></title><description><![CDATA[<p>Manfred T. schrieb:</p>
<blockquote>
<p>SCNR schrieb:</p>
<blockquote>
<p>Na so:</p>
<pre><code class="language-cpp">class Test {
  public:
  Test(const char *name) {
    if(name == NULL)
      initialized = false;
    else
      initialized = true;
    this-&gt;name = name;
  }

  bool is_initialized() {
     return initialized;
  }

  private:
    boost initialized;
    std::string name;
};
</code></pre>
</blockquote>
<p>Ist daran etwas schlecht? Ich mache das auch immer so.</p>
</blockquote>
<p>Falls der Aufruf des Ctors mit name == 0 ein Fehler ist, dann ist dieser Code ziemlich schlecht.</p>
<p>Eine Kunde muss is_initialized() verwenden, um den Fehler festzustellen. Das kann er aber auch lassen (aus Faulheit? aus Unkenntnis?). Unabhängig davon kann man einen solchen Fehler einfach ignorieren und mit einem solchen Test-Objekt hantieren, als wenn nichts wäre. Innerhalb von Test kann man nicht davon ausgehen, dass Test::name nie 0 ist. Undsoweiter.</p>
<p>Ich versteh nicht, warum ihr nicht einfach eine Exception werft!</p>
<p>Stefan.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1758882</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1758882</guid><dc:creator><![CDATA[DStefan]]></dc:creator><pubDate>Tue, 11 Aug 2009 13:49:37 GMT</pubDate></item><item><title><![CDATA[Reply to Fehler im Konstruktor -&amp;gt; sinnvolle Reaktion? on Tue, 11 Aug 2009 13:55:52 GMT]]></title><description><![CDATA[<p>DStefan schrieb:</p>
<blockquote>
<p>Ich versteh nicht, warum ihr nicht einfach eine Exception werft!</p>
</blockquote>
<p>Es gibt nur jemand, welcher bisher zu einer Lösung ohne Exception geraten hat. Und dessen Name ist SCNR -&gt; Sorry Could Not Resist -&gt; Troll.</p>
<p>Also erklär mir mal dieses &quot;ihr&quot; <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f921.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--clown_face"
      title=":clown:"
      alt="🤡"
    /></p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1758885</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1758885</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Tue, 11 Aug 2009 13:55:52 GMT</pubDate></item><item><title><![CDATA[Reply to Fehler im Konstruktor -&amp;gt; sinnvolle Reaktion? on Tue, 11 Aug 2009 14:09:16 GMT]]></title><description><![CDATA[<p>Dravere schrieb:</p>
<blockquote>
<p>...<br />
Also erklär mir mal dieses &quot;ihr&quot; <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f921.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--clown_face"
      title=":clown:"
      alt="🤡"
    /></p>
<p>Grüssli</p>
</blockquote>
<p>Das waren Manfred T. und SCNR siehe</p>
<p>Manfred T. schrieb:</p>
<blockquote>
<p>SCNR schrieb:</p>
<blockquote>
<p>Na so:</p>
<pre><code class="language-cpp">class Test {
  public:
  Test(const char *name) {
    if(name == NULL)
      initialized = false;
    else
      initialized = true;
    this-&gt;name = name;
  }

  bool is_initialized() {
     return initialized;
  }

  private:
    boost initialized;
    std::string name;
};
</code></pre>
</blockquote>
<p>Ist daran etwas schlecht? Ich mache das auch immer so.</p>
</blockquote>
<p><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /> <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f921.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--clown_face"
      title=":clown:"
      alt="🤡"
    /> <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f921.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--clown_face"
      title=":clown:"
      alt="🤡"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1758905</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1758905</guid><dc:creator><![CDATA[Tobi_logoff]]></dc:creator><pubDate>Tue, 11 Aug 2009 14:09:16 GMT</pubDate></item><item><title><![CDATA[Reply to Fehler im Konstruktor -&amp;gt; sinnvolle Reaktion? on Tue, 11 Aug 2009 14:34:51 GMT]]></title><description><![CDATA[<p>Dravere schrieb:</p>
<blockquote>
<p>SCNR -&gt; Sorry Could Not Resist -&gt; Troll.</p>
</blockquote>
<p>Danke für den Hinweis. Ist das Standard? <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>NAFAL -&gt; Need a fucking acronym lexicon -&gt; Stefan.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1758930</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1758930</guid><dc:creator><![CDATA[DStefan]]></dc:creator><pubDate>Tue, 11 Aug 2009 14:34:51 GMT</pubDate></item><item><title><![CDATA[Reply to Fehler im Konstruktor -&amp;gt; sinnvolle Reaktion? on Tue, 11 Aug 2009 14:40:51 GMT]]></title><description><![CDATA[<p>DStefan schrieb:</p>
<blockquote>
<p>Dravere schrieb:</p>
<blockquote>
<p>SCNR -&gt; Sorry Could Not Resist -&gt; Troll.</p>
</blockquote>
<p>Danke für den Hinweis. Ist das Standard? <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>NAFAL -&gt; Need a fucking acronym lexicon -&gt; Stefan.</p>
</blockquote>
<p>Ja, SCNR ist durchaus verbreitet.</p>
<p>Mir ist die Sache mit den Exceptions aber leider noch nicht ganz klar geworden. In welcher Situation muss ich den reservierten Speicher selber freigeben und in welchen Situationen passiert das automatisch? Das alles im Bezug auf Exceptions im Konstruktor, die entweder durch Membervariablen oder eventuell sogar selber im betrachteten Konstruktor geworfen werden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1758931</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1758931</guid><dc:creator><![CDATA[asdasdasd]]></dc:creator><pubDate>Tue, 11 Aug 2009 14:40:51 GMT</pubDate></item><item><title><![CDATA[Reply to Fehler im Konstruktor -&amp;gt; sinnvolle Reaktion? on Tue, 11 Aug 2009 14:45:08 GMT]]></title><description><![CDATA[<p>DStefan schrieb:</p>
<blockquote>
<p>Dravere schrieb:</p>
<blockquote>
<p>SCNR -&gt; Sorry Could Not Resist -&gt; Troll.</p>
</blockquote>
<p>Danke für den Hinweis. Ist das Standard? <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>NAFAL -&gt; Need a fucking acronym lexicon -&gt; Stefan.</p>
</blockquote>
<p>Hier:<br />
<a href="http://de.wikipedia.org/wiki/Liste_der_Abk%FCrzungen_(Netzjargon)" rel="nofollow">http://de.wikipedia.org/wiki/Liste_der_Abk%FCrzungen_(Netzjargon)</a><br />
<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>asdasdasd schrieb:</p>
<blockquote>
<p>Mir ist die Sache mit den Exceptions aber leider noch nicht ganz klar geworden. In welcher Situation muss ich den reservierten Speicher selber freigeben und in welchen Situationen passiert das automatisch? Das alles im Bezug auf Exceptions im Konstruktor, die entweder durch Membervariablen oder eventuell sogar selber im betrachteten Konstruktor geworfen werden.</p>
</blockquote>
<p>Halte dich einfach an RAII (<em>resource acquisition is initialization</em>), dann geht es ohne Probleme. Zu RAII solltest du genügend im Netz finden.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1758935</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1758935</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Tue, 11 Aug 2009 14:45:08 GMT</pubDate></item><item><title><![CDATA[Reply to Fehler im Konstruktor -&amp;gt; sinnvolle Reaktion? on Tue, 11 Aug 2009 14:59:05 GMT]]></title><description><![CDATA[<p>Dravere schrieb:</p>
<blockquote>
<p>asdasdasd schrieb:</p>
<blockquote>
<p>Mir ist die Sache mit den Exceptions aber leider noch nicht ganz klar geworden. In welcher Situation muss ich den reservierten Speicher selber freigeben und in welchen Situationen passiert das automatisch? Das alles im Bezug auf Exceptions im Konstruktor, die entweder durch Membervariablen oder eventuell sogar selber im betrachteten Konstruktor geworfen werden.</p>
</blockquote>
<p>Halte dich einfach an RAII (<em>resource acquisition is initialization</em>), dann geht es ohne Probleme. Zu RAII solltest du genügend im Netz finden.</p>
<p>Grüssli</p>
</blockquote>
<p>Mir ist das Prinzip eigentlich klar, nur empfinde ich die Sache mit new als ein Spezialfall.</p>
<p>In einigen Fällen brauche ich einfach einen Zeiger, da ich nicht extra eine Funktion init() schreiben will.</p>
<p>Wenn ich aber folgendes habe:</p>
<pre><code class="language-cpp">class MyClass
{
 ClassA *a;
 ClassB *b;
 ClassC c;

 MyClass() : a(new ClassA)
 {
  try
  {
   b = new ClassB;

   if (!c.ready())
   {
    throw eMyClassNotReady();
   }
  }
  catch (...)
  {
   cleanup(); // Notwendig?
   throw;
  }
 }

 ~MyClass()
 {
  cleanup();
 }

 void cleanup()
 {
  delete a;
  delete b;
 }
};
</code></pre>
<p>Wie sieht es in diesem Fall mit Speicherfreigabe aus? Muss ich etwas freigeben?</p>
<p>Ich sehe das momentan so:</p>
<p>Für c wird der Destruktor automatisch aufgerufen, kein Problem<br />
Für a und b geschieht das jedoch nicht, da das Objekt nicht vollständig erzeugt werden konnte und daher der Destruktor nicht aufgerufen wird.</p>
<p>Aber ich bin mir da eben nicht sicher und deswegen frage ich nun hier <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/1758941</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1758941</guid><dc:creator><![CDATA[asdasdasd]]></dc:creator><pubDate>Tue, 11 Aug 2009 14:59:05 GMT</pubDate></item><item><title><![CDATA[Reply to Fehler im Konstruktor -&amp;gt; sinnvolle Reaktion? on Tue, 11 Aug 2009 15:06:46 GMT]]></title><description><![CDATA[<p>Ja, cleanup ist hier notwendig. RAII macht schlussendlich auch nichts anderes, als das, allerdings einfach automatisch.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1758947</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1758947</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Tue, 11 Aug 2009 15:06:46 GMT</pubDate></item><item><title><![CDATA[Reply to Fehler im Konstruktor -&amp;gt; sinnvolle Reaktion? on Tue, 11 Aug 2009 15:08:54 GMT]]></title><description><![CDATA[<p>1. Du solltest <code>b</code> mit 0 initialisieren, damit es keine bösen Überraschungen gibt.<br />
2. Ja, das <code>cleanup</code> ist notwendig.<br />
3. Du verwendest hier aber nicht RAII! Mit RAII wäre nämlich ein <code>cleanup</code> gar nicht nötig.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1758950</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1758950</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Tue, 11 Aug 2009 15:08:54 GMT</pubDate></item><item><title><![CDATA[Reply to Fehler im Konstruktor -&amp;gt; sinnvolle Reaktion? on Tue, 11 Aug 2009 15:14:15 GMT]]></title><description><![CDATA[<p>Dravere schrieb:</p>
<blockquote>
<p>1. Du solltest <code>b</code> mit 0 initialisieren, damit es keine bösen Überraschungen gibt.</p>
</blockquote>
<p>Stimmt, sehe ich natürlich ein <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>
<p>Dravere schrieb:</p>
<blockquote>
<p>3. Du verwendest hier aber nicht RAII! Mit RAII wäre nämlich ein <code>cleanup</code> gar nicht nötig.</p>
</blockquote>
<p>Das heißt dann wohl ich muss <code>auto_ptr</code> nutzen <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/1758953</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1758953</guid><dc:creator><![CDATA[asdasdasd]]></dc:creator><pubDate>Tue, 11 Aug 2009 15:14:15 GMT</pubDate></item><item><title><![CDATA[Reply to Fehler im Konstruktor -&amp;gt; sinnvolle Reaktion? on Tue, 11 Aug 2009 16:51:51 GMT]]></title><description><![CDATA[<p>asdasdasd schrieb:</p>
<blockquote>
<p>Das heißt dann wohl ich muss <code>auto_ptr</code> nutzen <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>
</blockquote>
<p>Oder besser: die Smartpointer des TR1 oder von boost (scoped_ptr, shared_ptr, intrusive_ptr)...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1759000</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1759000</guid><dc:creator><![CDATA[asc]]></dc:creator><pubDate>Tue, 11 Aug 2009 16:51:51 GMT</pubDate></item><item><title><![CDATA[Reply to Fehler im Konstruktor -&amp;gt; sinnvolle Reaktion? on Tue, 11 Aug 2009 19:46:26 GMT]]></title><description><![CDATA[<p>asc schrieb:</p>
<blockquote>
<p>Oder besser: die Smartpointer des TR1 oder von boost (scoped_ptr, shared_ptr, intrusive_ptr)...</p>
</blockquote>
<p>Würde ich nicht verallgemeinern. Okay, als Member ist <code>auto_ptr</code> vielleicht nicht immer optimal, sonst hat er aber einige Anwendungsbereiche (als eines der wenigen Konstrukte, die im jetzigen Standard schon eine Art Move-Semantik bieten). <code>shared_ptr</code> wird meiner Meinung nach viel zu oft an Stellen eingesetzt, an denen man sich keine Gedanken um Besitzverhältnisse macht. Und <code>intrusive_ptr</code> braucht man eigentlich recht selten bis nie, wenns nur um RAII geht...</p>
<p>Davon abgesehen bringen alle diese Smart Pointer nichts, wenn jedes Objekt seinen Speicherbereich selbst verwaltet und ein sinnvolles Kopieren möglich sein soll. Schliesslich möchte man nicht immer alles teilen. Dann ist man trotzdem wieder zu einer Alternative gezwungen (sei es jetzt manuelle Verwaltung durch die Grossen Drei, Container im Falle von mehreren Objekten oder ein spezieller Smart-Pointer mit Kopiersemantik).</p>
<p>Aber falls die Klasse nicht kopierbar sein soll und man RAII und damit Exceptionsicherheit erreichen möchte, ist ein <code>scoped_ptr</code> erste Wahl.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1759069</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1759069</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Tue, 11 Aug 2009 19:46:26 GMT</pubDate></item><item><title><![CDATA[Reply to Fehler im Konstruktor -&amp;gt; sinnvolle Reaktion? on Tue, 11 Aug 2009 20:38:14 GMT]]></title><description><![CDATA[<p>asdasdasd schrieb:</p>
<blockquote>
<p>In einigen Fällen brauche ich einfach einen Zeiger, da ich nicht extra eine Funktion init() schreiben will.</p>
</blockquote>
<p>Was ist <em>das</em> denn für eine Begründung?</p>
<p>asdasdasd schrieb:</p>
<blockquote>
<p>Wenn ich aber folgendes habe:</p>
<pre><code class="language-cpp">class MyClass
{
 ClassA *a;
 ClassB *b;
 ClassC c;

 MyClass() : a(new ClassA)
 {
  try
  {
   b = new ClassB;
   
   if (!c.ready())
   {
    throw eMyClassNotReady();
   }
  }
  catch (...)
  {
   cleanup(); // Notwendig?
   throw;
  }
 }

 ~MyClass()
 {
  cleanup();
 }

 void cleanup()
 {
  delete a;
  delete b;
 }
};
</code></pre>
</blockquote>
<p>Oha! Wenn das Erzeugen/Initialisieren von *a schief läuft und dann cleanup aufgerufen wird, fürhst Du &quot;delete b&quot; aus, wobei b aber noch gar nicht initialisiert wurde -- noch nicht mal mit dem Nullzeiger.</p>
<p>Warum nicht einfach ohne Zeiger? Ich sehe dem Beispiel nicht an, warum es notwendig sei, Zeiger zu speichern. Du machst den Code nur fehleranfällig damit. Beispielsweise hast Du die Dreierregel nicht befolgt. (!!)</p>
<p>Muss das mit c.ready() sein? Kann nicht einfach der Konstruktor von C die Exception schmeißen?</p>
<p>Dravere sagte: &quot;Halte Dich an RAII&quot;. Das hast Du hier nur eher halbherzig befolgt. Idealerweise verwalten sich auch die Elemente selbst, soweit das geht. Das ist bequem und weniger fehleranfällig. Das geht natürlich nicht immer (wie soll man sonst std::vector implementieren?). Aber man sollte versuchen, die Zahl der explizit zu verwaltenden Resourcen pro Objekt auf 0 oder 1 zu reduzieren. Das kriegt man hin, in dem man den Verwaltungsaufwand in die &quot;Objektelemente verlagert&quot;. Rohe Zeiger können das natürlich nicht. Bei Dir sind's zwei Zeiger. Gut, das ist noch vertretbar, aber es erfordert Vorsicht und ist fehleranfällig. Ich hätte es wahrscheinlich über auto_ptr gelöst:</p>
<pre><code class="language-cpp">class MyClass {
  ...

  explicit MyClass(FactoryA &amp; pfa, FactoryB &amp; pfb)
  : a(0), b(0)
  {
    auto_ptr&lt;ClassA&gt; apa (pfa-&gt;make());
    auto_ptr&lt;Classb&gt; apb (pfb-&gt;make());
    a = apa.release();
    b = apb.release();
  }

  ~MyClass()
  {
    delete b;
    delete a;
  }

  MyClass(MyClass const&amp; x)
  {
    // Dreierregel-Extra-Wurst!
  }

  MyClass&amp; operator=(MyClass const&amp; x)
  {
    // Dreierregel-Extra-Wurst!
  }

  ...
};
</code></pre>
<p>Das mit dem &quot;FactoryA&quot;, &quot;FactoryB&quot; ist etwas, mit dem man die Speicherung von Zeigern motivieren kann. Hier muss MyClass nicht wirklich wissen, was das für Objekte genau sind, Hauptsache sie erben von ClassA und ClassB, welche hoffentlich einen virtuellen Destruktor haben.</p>
<p>Beachte, wenn Du das A-Objekt und das B-Objekt direkt als Element der MyClasse benutzt hättest, bräuchtest Du auch keine &quot;Extra-Wurst&quot; bzgl Kopieren und Zuweisung. Warum? Die implizit vom Compiler definierten Operationen machen dann schon das Richtige.</p>
<p>asdasdasd schrieb:</p>
<blockquote>
<p>Wie sieht es in diesem Fall mit Speicherfreigabe aus? Muss ich etwas freigeben?<br />
Ich sehe das momentan so:<br />
Für c wird der Destruktor automatisch aufgerufen, kein Problem<br />
Für a und b geschieht das jedoch nicht, da das Objekt nicht vollständig erzeugt werden konnte und daher der Destruktor nicht aufgerufen wird.</p>
</blockquote>
<p>Du setzt den Zeiger mit dem Objekt, auf das gezeigt wird gleich. Typischer Anfängerfehler. a und b werden sauber zerstört. <em>Das worauf sie zeigen</em> aber nicht.</p>
<p>Gruß,<br />
SP</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1759099</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1759099</guid><dc:creator><![CDATA[Sebastian Pizer]]></dc:creator><pubDate>Tue, 11 Aug 2009 20:38:14 GMT</pubDate></item><item><title><![CDATA[Reply to Fehler im Konstruktor -&amp;gt; sinnvolle Reaktion? on Tue, 11 Aug 2009 21:08:44 GMT]]></title><description><![CDATA[<p>Sebastian Pizer schrieb:</p>
<blockquote>
<p>Oha! Wenn das Erzeugen/Initialisieren von *a schief läuft und dann cleanup aufgerufen wird, fürhst Du &quot;delete b&quot; aus, wobei b aber noch gar nicht initialisiert wurde -- noch nicht mal mit dem Nullzeiger.</p>
</blockquote>
<p>Das war'n Vertipper. Sollte heißen &quot;...von b = new ClassB schief läuft...&quot;</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1759116</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1759116</guid><dc:creator><![CDATA[Sebastian Pizer]]></dc:creator><pubDate>Tue, 11 Aug 2009 21:08:44 GMT</pubDate></item></channel></rss>