<?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[Fehlerhandling im Konstruktor]]></title><description><![CDATA[<p>Hallo,</p>
<p>ist es möglich, im Konstruktor auf einen aufgetretenen Fehler zu reagieren, und dies der instanzierenden Klasse mitzuteilen?<br />
Über Flags und Errorcallbacks möchte ich dies nicht realisieren.</p>
<p>Kann man &quot;MyClass&quot; auf &quot;NULL&quot; setzen, so dass ich dies in der übergeordneten Klasse dann prüfen kann?</p>
<pre><code>MyClass::MyClass(char *pcFilename)
{
  File *pFile;
  if((pFile = fopen(pcFilename, &quot;r&quot;)) == NULL)
  {
    //geht so natürlich nicht
    this = NULL;
    return;
  }
}
</code></pre>
<p>mfg</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/299613/fehlerhandling-im-konstruktor</link><generator>RSS for Node</generator><lastBuildDate>Thu, 13 Aug 2026 03:29:06 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/299613.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 15 Feb 2012 07:20:59 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Fehlerhandling im Konstruktor on Wed, 15 Feb 2012 07:20:59 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>ist es möglich, im Konstruktor auf einen aufgetretenen Fehler zu reagieren, und dies der instanzierenden Klasse mitzuteilen?<br />
Über Flags und Errorcallbacks möchte ich dies nicht realisieren.</p>
<p>Kann man &quot;MyClass&quot; auf &quot;NULL&quot; setzen, so dass ich dies in der übergeordneten Klasse dann prüfen kann?</p>
<pre><code>MyClass::MyClass(char *pcFilename)
{
  File *pFile;
  if((pFile = fopen(pcFilename, &quot;r&quot;)) == NULL)
  {
    //geht so natürlich nicht
    this = NULL;
    return;
  }
}
</code></pre>
<p>mfg</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2181294</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2181294</guid><dc:creator><![CDATA[tinyoon]]></dc:creator><pubDate>Wed, 15 Feb 2012 07:20:59 GMT</pubDate></item><item><title><![CDATA[Reply to Fehlerhandling im Konstruktor on Wed, 15 Feb 2012 07:26:26 GMT]]></title><description><![CDATA[<p>Du kannst im Konstruktor eine Exception werfen, was dazu führt dass das Objekt garnicht erst erzeugt wird.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2181296</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2181296</guid><dc:creator><![CDATA[LordJaxom]]></dc:creator><pubDate>Wed, 15 Feb 2012 07:26:26 GMT</pubDate></item><item><title><![CDATA[Reply to Fehlerhandling im Konstruktor on Wed, 15 Feb 2012 07:26:47 GMT]]></title><description><![CDATA[<p>Eleganterweise mit exceptions</p>
<p>tinyoon schrieb:</p>
<blockquote>
<pre><code class="language-cpp">MyClass::MyClass(char *pcFilename) throw(YourErrorException)
{
  File *pFile;
  if((pFile = fopen(pcFilename, &quot;r&quot;)) == NULL)
  {
    //geht so natürlich nicht
    throw YourErrorException();
  }
}
</code></pre>
<p>mfg</p>
</blockquote>
]]></description><link>https://www.c-plusplus.net/forum/post/2181297</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2181297</guid><dc:creator><![CDATA[PhilippHToner]]></dc:creator><pubDate>Wed, 15 Feb 2012 07:26:47 GMT</pubDate></item><item><title><![CDATA[Reply to Fehlerhandling im Konstruktor on Wed, 15 Feb 2012 07:44:52 GMT]]></title><description><![CDATA[<p>Klasse.<br />
Danke für die schnelle Hilfe, so funktioniert es sauber:)</p>
<p>mfg</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2181302</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2181302</guid><dc:creator><![CDATA[tinyoon]]></dc:creator><pubDate>Wed, 15 Feb 2012 07:44:52 GMT</pubDate></item><item><title><![CDATA[Reply to Fehlerhandling im Konstruktor on Wed, 15 Feb 2012 07:48:21 GMT]]></title><description><![CDATA[<p>PhilippHToner schrieb:</p>
<blockquote>
<p>Eleganterweise mit exceptions</p>
</blockquote>
<p>Das würde ich aber nicht übertreiben. Ich würde das dann tun wenn ich unbedingt eine Invariante unbedingt brauche oder es wirklich einen schwerwiegenden Fehler betrifft, für den sich auch der Benutzer der Klasse interessiert, d.h. den er auch behandeln sollte. So wie das bei dir aussieht würde ich mich z.B. lieber am interface der iostreams orientieren und keine exception werfen (stattdessen das Objekt auf einen NULL-Zusand setzen). Exceptions sind keine Rückgabewerte.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2181303</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2181303</guid><dc:creator><![CDATA[GorbGorb]]></dc:creator><pubDate>Wed, 15 Feb 2012 07:48:21 GMT</pubDate></item><item><title><![CDATA[Reply to Fehlerhandling im Konstruktor on Wed, 15 Feb 2012 08:02:15 GMT]]></title><description><![CDATA[<p>GorbGorb schrieb:</p>
<blockquote>
<p>PhilippHToner schrieb:</p>
<blockquote>
<p>Eleganterweise mit exceptions</p>
</blockquote>
<p>Das würde ich aber nicht übertreiben. Ich würde das dann tun wenn ich unbedingt eine Invariante unbedingt brauche oder es wirklich einen schwerwiegenden Fehler betrifft, für den sich auch der Benutzer der Klasse interessiert, d.h. den er auch behandeln sollte. So wie das bei dir aussieht würde ich mich z.B. lieber am interface der iostreams orientieren und keine exception werfen (stattdessen das Objekt auf einen NULL-Zusand setzen). Exceptions sind keine Rückgabewerte.</p>
</blockquote>
<p>Naja wir coden hier C++ also wieso keine exceptions? Klar kann man auch den bool operator!() implementieren, der beim Fehler true wird wie es die stream anbieten. Es kommt halt drauf an, inwiefern es fatal ist, wenn der stream zur Datei nicht geöffnet wird. Wenn ich ein Programm bau, z.B. eine Datei verschlüsselt ist sowas auf jeden Fall eine exception Wert, weil das Programm ansonsten keine Aufgaben mehr erledigen kann. Wenn das Programm beispielsweise einfach Dateien durchsucht und manche Dateien erlauben das Lesen oder SChreiben nicht, dann könnte man mit sanften Zuständen arbeiten ja <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/2181309</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2181309</guid><dc:creator><![CDATA[PhilippHToner]]></dc:creator><pubDate>Wed, 15 Feb 2012 08:02:15 GMT</pubDate></item><item><title><![CDATA[Reply to Fehlerhandling im Konstruktor on Wed, 15 Feb 2012 09:31:03 GMT]]></title><description><![CDATA[<p>GorbGorb schrieb:</p>
<blockquote>
<p>So wie das bei dir aussieht würde ich mich z.B. lieber am interface der iostreams orientieren und keine exception werfen (stattdessen das Objekt auf einen NULL-Zusand setzen). Exceptions sind keine Rückgabewerte.</p>
</blockquote>
<p>Ja, und ich behaupte das Gegenteil.<br />
Objekte mit Zombie-Zustand sind Mist.<br />
Klassen mit &quot;vielleicht&quot; Konstruktor sind ebenso Mist.<br />
Wenn man umbedingt Zombie-Files anbieten will, kann man immer noch einen Default-Ctor + TryOpen() Funktion machen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2181338</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2181338</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Wed, 15 Feb 2012 09:31:03 GMT</pubDate></item><item><title><![CDATA[Reply to Fehlerhandling im Konstruktor on Wed, 15 Feb 2012 12:13:26 GMT]]></title><description><![CDATA[<p>GorbGorb schrieb:</p>
<blockquote>
<p>So wie das bei dir aussieht würde ich mich z.B. lieber am interface der iostreams orientieren und keine exception werfen (stattdessen das Objekt auf einen NULL-Zusand setzen).</p>
</blockquote>
<p>Jein. Wenn das Feature der Klasse, dessen Erzeugung Probleme macht, ein optionales Feature ist, dann braucht und sollte man keine Exceptions werfen. Wenn andersrum das Feature ein must-have ist und die Existenz eines Objekts ohne dieses Feature keinen Sinn macht, dann sollte man Exceptions werfen und sich nicht mit Zombies abgeben.<br />
std::fstreams sind da in einer Grazone - Ein Stream, der nicht streamen kann, weil er keiner Datei zugeordnet ist, macht eigentlich keinen Sinn. Andererseits möchte man vielleicht die Ausgabe &quot;verteilen&quot;, d.h. den stream zwischendurch auf eine andere Datei umleiten, oder man möchte mangels anderer Möglichkeiten vielleicht erstmal schauen, ob die Zieldatei existiert/beschreibbar ist etc. Dazu ist ein öffnen/schließen von Dateien sinnvoll und es muss der besagte Kompromiss mit isopen() und ohne Exceptions eingeganen werden.<br />
Das ist aber ein Spezialfall und sollte nicht als allgemeines Designpattern für Konstruktorfehler kopiert werden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2181402</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2181402</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Wed, 15 Feb 2012 12:13:26 GMT</pubDate></item><item><title><![CDATA[Reply to Fehlerhandling im Konstruktor on Wed, 15 Feb 2012 16:02:53 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>Wenn man umbedingt Zombie-Files anbieten will, kann man immer noch einen Default-Ctor + TryOpen() Funktion machen.</p>
</blockquote>
<p>Das fände ich auch schöner.<br />
Das Problem an exceptions ist doch, dass ihre performance Charakteristika für einen sehr seltenen Gebrauch sprechen (eben bei außergewöhnlichen Situationen). Wenn man aber eine Klasse oder eine Funktion schreibt, die immer wieder in unterschiedlichen Kontexten verwendet wird, kann man nicht genau bewerten, ob ein Fehler jetzt unerwartet aufkommt oder vielleicht nur auf ein Auftreten dieses Fehlers geprüft wurde. Ein Beispiel von boost, das ich so nicht schön finde:</p>
<pre><code class="language-cpp">int main(int argc, char * argv[])
{
    using boost::lexical_cast;
    using boost::bad_lexical_cast;

    std::vector&lt;short&gt; args;

    while(*++argv)
    {
        try
        {
            args.push_back(lexical_cast&lt;short&gt;(*argv));
        }
        catch(bad_lexical_cast &amp;)
        {
            args.push_back(0);
        }
    }
    ...
}
</code></pre>
<p><a href="http://www.boost.org/doc/libs/1_48_0/doc/html/boost_lexical_cast/examples.html" rel="nofollow">http://www.boost.org/doc/libs/1_48_0/doc/html/boost_lexical_cast/examples.html</a><br />
Fühlt sich das nur für mich falsch an? Es wäre meines Erachtens nach einfach sinnvoller ein Objekt im &quot;Zombiezustand&quot; zurückzugeben (z.B. boost::optional) und den user entscheiden zu lassen, ob jetzt was Ernsthaftes schief gegangen ist oder nicht.<br />
Was ich im Grunde sagen will: Was eine exception Wert ist kontextabhängig, man sollte es daher nicht übertreiben, vor allem bei häufig wiederverwendetem code. Normale Logik in einen catch Block zu schreiben (wie in dem Beispiel oben) ist schlechter Stil.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2181529</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2181529</guid><dc:creator><![CDATA[GorbGorb]]></dc:creator><pubDate>Wed, 15 Feb 2012 16:02:53 GMT</pubDate></item><item><title><![CDATA[Reply to Fehlerhandling im Konstruktor on Wed, 15 Feb 2012 17:09:21 GMT]]></title><description><![CDATA[<p>Also ich habe mal nachgelesen, dass exception handling NICHT langsamer ist. Es gibt einen Art exception handling (LIFO) Stack, der beim Eintreten in einen try block einfach pushed wird mit den catch Ausdrücken und beim Austreten all diese wieder gepopt werden. Wenn nun eine exception geworfen wird muss das Prog einfach zur Laufzeit den Stack von oben nach unten durchsuchen und an die Adresse jumpen.</p>
<p>Klar, wenn der Code im 135. Try Block ist, und ich schmeiss ne exception, die ganz früh catched wurde, müssen halt viele compares gemacht werden.</p>
<p>Kann sein, dass der Compiler es auch noch optimieren kann, weiß ich nicht. Aber theoretisch müsste er mit den generierten Klassen-Ids arbeiten, weil es zur Laufzeit keine Klassen gibt und exception handling ja auch mit vererbten Klassen funktioniert. Also sowas wie die Funktionstabelle virtueller Funktionen.</p>
<p>Unabhängig, wie performant sie arbeiten, ist es einfach so, dass viele ein Problem mit der alten Programmierung haben, wo man mit goto und Marken gearbeitet hat und deswegen Exception und switch Blöcke nicht erwünscht sind.<br />
Nach dem Motto: das Programm arbeitet Blöcke von oben nach unten ab.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2181577</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2181577</guid><dc:creator><![CDATA[PhilippHToner]]></dc:creator><pubDate>Wed, 15 Feb 2012 17:09:21 GMT</pubDate></item><item><title><![CDATA[Reply to Fehlerhandling im Konstruktor on Wed, 15 Feb 2012 17:39:26 GMT]]></title><description><![CDATA[<p>PhilippHToner schrieb:</p>
<blockquote>
<p>Also ich habe mal nachgelesen, dass exception handling NICHT langsamer ist. Es gibt einen Art exception handling (LIFO) Stack, der beim Eintreten in einen try block einfach pushed wird mit den catch Ausdrücken und beim Austreten all diese wieder gepopt werden. Wenn nun eine exception geworfen wird muss das Prog einfach zur Laufzeit den Stack von oben nach unten durchsuchen und an die Adresse jumpen.</p>
</blockquote>
<p>Soviel ich weiß müssten exceptions nichts kosten, solange sie nicht geworfen werden. Wenn sie aber dann doch fliegen ist der performance overhead deutlich höher als bei einem simplen return.<br />
Exceptions sind aber nur ein Aspekt, warum man es nicht übertreiben sollte. Der andere ist, dass man Logik in catch Blöcke schreiben muss (siehe boost Beispiel).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2181585</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2181585</guid><dc:creator><![CDATA[GorbGorb]]></dc:creator><pubDate>Wed, 15 Feb 2012 17:39:26 GMT</pubDate></item></channel></rss>