<?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[Try-Catch-Finally Ersatz]]></title><description><![CDATA[<p>Hallo zusammen<br />
Je länger ich mit C++ programmiere, desto mehr vermisse ich das finally statement aus anderen Sprachen... Wie macht ihr das eigentlich mit dem Speicheraufräumen? Ich höre diesbezüglich oft, dass dies ja die Destruktoren für einem erledigen, aber bei vielen Aufgaben benötigt man ja Hilfstrukturen wie ein temporäres Array (auf dem Heap) oder Dateihandles und so weiter. Es ist einfach obermühsam, dies an jeder Stelle, wo eine routine beenden könnte, zu schliessen:</p>
<pre><code class="language-cpp">void MyFunc(void){
 uint16  *aIdx = new uint16[erstzurlaufzeit bekannt];
 File     hFle = CreateFile(irgendwas);
 float32 *pBuf = new float32[auch erst zur Laufzeit bekannt];

 // hier kommt ein Codeblock

 if(Hier geht etwas schief){
  delete []aIdx;
  CloseHandle(hFle);
  delete []pBuf;
  throw MyException;
 }

 // hier kommt ein weiterer Codeblock

 if(Hier geht etwas schief){
  delete []aIdx;
  CloseHandle(hFle);
  delete []pBuf;
  throw MyException;
 }

 // hier kommt noch mehr Code

 if(Hier geht etwas schief){
  delete []aIdx;
  CloseHandle(hFle);
  delete []pBuf;
  throw MyException;
 }

 // an dieser Stelle muss ich natürlich noch mal aufräumen...
  delete []aIdx;
  CloseHandle(hFle);
  delete []pBuf;
}
</code></pre>
<p>Aus Java kenne ich es so:</p>
<pre><code class="language-cpp">void MyFunc(void){
 uint16  *aIdx = new uint16[erstzurlaufzeit bekannt];
 File     hFle = CreateFile(irgendwas);
 float32 *pBuf = new float32[auch erst zur Laufzeit bekannt];

 try{
  // hier kommt ein Codeblock
  if(Hier geht etwas schief) throw MyException;
  // hier kommt ein weiterer Codeblock
  if(Hier geht etwas schief) throw MyException;
  // hier kommt noch mehr Code
  if(Hier geht etwas schief) throw MyException;
 }
 catch(Exception exp){
  // hier kann ich noch exceptions behandeln
 }
 finally{
  // Dieser Code wird auf JEDEN Fall ausgeführt, egal ob die Methode via
  // return, throw oder durch verlassen des Scopes verlassen wird...
  delete []aIdx;
  CloseHandle(hFle);
  delete []pBuf;
 }
}
</code></pre>
<p>Bitte!!! Ich möchte hier keine Debatte über C++ vs. Java starten. Mich interessiert wie ihr mit solchen Situationen umgeht, weil ich diesbezüglich in meinem aktuellen C++ Projekt (Bachelor Thesis) Verbesserungspotential sehe <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>Mfg Samuel</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/264314/try-catch-finally-ersatz</link><generator>RSS for Node</generator><lastBuildDate>Fri, 04 Sep 2026 08:45:16 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/264314.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 06 Apr 2010 09:23:43 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Try-Catch-Finally Ersatz on Tue, 06 Apr 2010 09:24:53 GMT]]></title><description><![CDATA[<p>Hallo zusammen<br />
Je länger ich mit C++ programmiere, desto mehr vermisse ich das finally statement aus anderen Sprachen... Wie macht ihr das eigentlich mit dem Speicheraufräumen? Ich höre diesbezüglich oft, dass dies ja die Destruktoren für einem erledigen, aber bei vielen Aufgaben benötigt man ja Hilfstrukturen wie ein temporäres Array (auf dem Heap) oder Dateihandles und so weiter. Es ist einfach obermühsam, dies an jeder Stelle, wo eine routine beenden könnte, zu schliessen:</p>
<pre><code class="language-cpp">void MyFunc(void){
 uint16  *aIdx = new uint16[erstzurlaufzeit bekannt];
 File     hFle = CreateFile(irgendwas);
 float32 *pBuf = new float32[auch erst zur Laufzeit bekannt];

 // hier kommt ein Codeblock

 if(Hier geht etwas schief){
  delete []aIdx;
  CloseHandle(hFle);
  delete []pBuf;
  throw MyException;
 }

 // hier kommt ein weiterer Codeblock

 if(Hier geht etwas schief){
  delete []aIdx;
  CloseHandle(hFle);
  delete []pBuf;
  throw MyException;
 }

 // hier kommt noch mehr Code

 if(Hier geht etwas schief){
  delete []aIdx;
  CloseHandle(hFle);
  delete []pBuf;
  throw MyException;
 }

 // an dieser Stelle muss ich natürlich noch mal aufräumen...
  delete []aIdx;
  CloseHandle(hFle);
  delete []pBuf;
}
</code></pre>
<p>Aus Java kenne ich es so:</p>
<pre><code class="language-cpp">void MyFunc(void){
 uint16  *aIdx = new uint16[erstzurlaufzeit bekannt];
 File     hFle = CreateFile(irgendwas);
 float32 *pBuf = new float32[auch erst zur Laufzeit bekannt];

 try{
  // hier kommt ein Codeblock
  if(Hier geht etwas schief) throw MyException;
  // hier kommt ein weiterer Codeblock
  if(Hier geht etwas schief) throw MyException;
  // hier kommt noch mehr Code
  if(Hier geht etwas schief) throw MyException;
 }
 catch(Exception exp){
  // hier kann ich noch exceptions behandeln
 }
 finally{
  // Dieser Code wird auf JEDEN Fall ausgeführt, egal ob die Methode via
  // return, throw oder durch verlassen des Scopes verlassen wird...
  delete []aIdx;
  CloseHandle(hFle);
  delete []pBuf;
 }
}
</code></pre>
<p>Bitte!!! Ich möchte hier keine Debatte über C++ vs. Java starten. Mich interessiert wie ihr mit solchen Situationen umgeht, weil ich diesbezüglich in meinem aktuellen C++ Projekt (Bachelor Thesis) Verbesserungspotential sehe <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>Mfg Samuel</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1878157</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1878157</guid><dc:creator><![CDATA[Ishildur]]></dc:creator><pubDate>Tue, 06 Apr 2010 09:24:53 GMT</pubDate></item><item><title><![CDATA[Reply to Try-Catch-Finally Ersatz on Tue, 06 Apr 2010 09:32:56 GMT]]></title><description><![CDATA[<p>Mach aus</p>
<pre><code class="language-cpp">uint16  *aIdx = new uint16[erstzurlaufzeit bekannt];
 float32 *pBuf = new float32[auch erst zur Laufzeit bekannt];
</code></pre>
<p>dies:</p>
<pre><code class="language-cpp">std::vector&lt;uint16&gt; aIdx(erstzurlaufzeit bekannt);
 std::vector&lt;float32&gt; pBuf(auch erst zur Laufzeit bekannt);
</code></pre>
<p>Tada! Alle Probleme gelöst! Wird der Scope verlassen, beispielsweise durch eine Exception, wird der Destruktor vom vector aufgerufen und alle Ressourcen freigegeben. Das ist es was man meint, wenn man sagt, dass der Destruktor einem die Speicherverwaltung abnimmt. Das Stichwort zum Nachschlagen lautet <em>RAII</em>. Das kann (und sollte) man natürlich auch für eigene Klassen machen - man braucht sich nicht auf die Klassen der STL zu beschränken.</p>
<p>edit: Das gilt natürlich ebenso für offene Dateien. Nimm statt dem C-Konstrukt <code>File</code> einen <code>std::fstream</code> und alles ist automatisch in Ordnung.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1878161</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1878161</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Tue, 06 Apr 2010 09:32:56 GMT</pubDate></item><item><title><![CDATA[Reply to Try-Catch-Finally Ersatz on Tue, 06 Apr 2010 09:33:34 GMT]]></title><description><![CDATA[<p>RAII ist wohl eine elegante Möglichkeit (der Destruktor räumt auf, daher musst man seine delete-Statements nicht vor jedem möglichen Funktionsende verteilen).</p>
<p>EDIT: Es soll noch erwähnt werden, dass der Microsoft-Compiler die Erweiterung __try __finally bietet. Die lässt sich aber nicht mit C++-Exceptions mischen, ist nicht portabel usw...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1878162</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1878162</guid><dc:creator><![CDATA[_matze]]></dc:creator><pubDate>Tue, 06 Apr 2010 09:33:34 GMT</pubDate></item><item><title><![CDATA[Reply to Try-Catch-Finally Ersatz on Tue, 06 Apr 2010 09:35:38 GMT]]></title><description><![CDATA[<p>OK, einverstanden, aber was ist mit folgenden Konstrukten?</p>
<pre><code class="language-cpp">VertexBuffer *vb;
 IndexBuffer  *ib;

 vb-&gt;Lock();
 ib-&gt;Lock();
</code></pre>
<p>Diese müssen dann bei jedem verlassen wieder unlocked werden und wehe falls nicht. Das Objekt darf ich allerdings nicht zerstören...</p>
<p>Oder auch ganz schön hässlich:<br />
EnterCriticalSection();<br />
schade, wenn man diese nicht wieder verlässt, weil mans bei irgend einem return vergessen hat...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1878163</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1878163</guid><dc:creator><![CDATA[Ishildur]]></dc:creator><pubDate>Tue, 06 Apr 2010 09:35:38 GMT</pubDate></item><item><title><![CDATA[Reply to Try-Catch-Finally Ersatz on Tue, 06 Apr 2010 09:43:56 GMT]]></title><description><![CDATA[<p>Da bietet es sich dann an, anstatt den Lock als Klassenmethode zu haben, stattdessen eine Lock-Klasse zu schreiben, die dann bei Verlassen des Scopes den Lock wieder freigibt.</p>
<p>C++0x wird mit std::lock genau dies schon in den Standard aufnehmen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1878166</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1878166</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Tue, 06 Apr 2010 09:43:56 GMT</pubDate></item><item><title><![CDATA[Reply to Try-Catch-Finally Ersatz on Tue, 06 Apr 2010 10:07:32 GMT]]></title><description><![CDATA[<p>Du kannst nahezu alles Ressourcenmanagement mit RAII lösen. Der Vorteil gegenüber Try-Finally ist, dass der Code dafür nur einmal geschrieben werden muss (im Destruktor). Beim Verwenden muss man Ressourcen nicht mehr mit <code>finally</code> manuell freigeben.</p>
<p>Wichtig sind in C++ auch die Smart-Pointer, falls einzelne Zeiger mit dynamisch allokiertem Speicher vorhanden sind. Ein typischer RAII-Smart-Pointer ist der <code>boost::scoped_ptr</code> .</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1878177</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1878177</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Tue, 06 Apr 2010 10:07:32 GMT</pubDate></item><item><title><![CDATA[Reply to Try-Catch-Finally Ersatz on Tue, 06 Apr 2010 10:16:47 GMT]]></title><description><![CDATA[<p>Es gibt auch einen RAII Mutex boost::scoped_lock</p>
<p><a href="http://www.boost.org/doc/libs/1_37_0/doc/html/boost/interprocess/scoped_lock.html" rel="nofollow">http://www.boost.org/doc/libs/1_37_0/doc/html/boost/interprocess/scoped_lock.html</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1878184</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1878184</guid><dc:creator><![CDATA[blub* 0]]></dc:creator><pubDate>Tue, 06 Apr 2010 10:16:47 GMT</pubDate></item><item><title><![CDATA[Reply to Try-Catch-Finally Ersatz on Tue, 06 Apr 2010 10:28:09 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/1250">@Ishildur</a>:<br />
Alles das, und noch viel mehr, kann man mit RAII machen.<br />
Was locking angeht gibt es wie SeppJ/Nexus/blub² schon geschrieben haben fertige Klassen, wovon einige auch im neuen C++ Standard sein werden.<br />
Bis dahin kann man z.B. Boost.Thread verwenden. Oder sich einfach selbst was schreiben, sind ja nur ein paar Zeilen.</p>
<p>Aber wie gesagt, auch andere Dinge kann man so machen. Ich hatte z.B. öfters den Fall, dass ich eine Funktion aufrufen wollte, und/oder ein Bool-Flag setzen, falls in einer Funktion irgendwo was schief gegangen ist.</p>
<p>Konkret ging es um Objekte welche die logische Verbindung zu einem Gerät darstellen, wobei das Gerät über eine serielle Schnittstelle angebungen ist. Und wenn bei der Kommunikation irgendwas schief geht, macht es Sinn, ein Flag zu setzen, damit man beim nächsten &quot;Befehl&quot; weiss, dass man eine &quot;Recovery-Prozedur&quot; durchlaufen muss. D.h. FIFOs flushen + BREAK schicken + Warten etc. bevor man ein neues Kommando schickt.</p>
<p>Auch dazu kann man sich spezialisierte Guard-Klassen basteln, die das im Destruktor machen - und zwar nur, falls sie nicht &quot;entschärft&quot; worden sind.<br />
Einsatz dann ala so:</p>
<pre><code class="language-cpp">void foo::bar()
{
    foo_guard g(*this);

    // ... dinge ...

    g.dismiss(); // alles OK, guard entschärfen
}
</code></pre>
<p>Auch dazu gibt es bereits vorgefertigte Hilfsklassen, z.b. den ScopeGuard in der Loki:<br />
<a href="http://loki-lib.cvs.sourceforge.net/loki-lib/loki/include/loki/ScopeGuard.h?view=markup" rel="nofollow">http://loki-lib.cvs.sourceforge.net/loki-lib/loki/include/loki/ScopeGuard.h?view=markup</a></p>
<p>Auch shared_ptr aus der Boost lässt sich als Scope-Guard misbrauchen, wobei ich das persönlich nicht so toll finde.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1878190</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1878190</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 06 Apr 2010 10:28:09 GMT</pubDate></item><item><title><![CDATA[Reply to Try-Catch-Finally Ersatz on Tue, 06 Apr 2010 10:28:48 GMT]]></title><description><![CDATA[<p>zZt. gibts für sowas <a href="http://www.boost.org/doc/libs/1_42_0/doc/html/thread/synchronization.html#thread.synchronization.locks.lock_guard" rel="nofollow">boost::lock_guard</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1878202</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1878202</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Tue, 06 Apr 2010 10:28:48 GMT</pubDate></item><item><title><![CDATA[Reply to Try-Catch-Finally Ersatz on Sun, 18 Apr 2010 11:11:29 GMT]]></title><description><![CDATA[<p>Ich verstehs irgendwie nicht. Direct3D ist bspw. eine Statemaschine. Soll ich nun für jede Eigenschaft die ich schreibe, eine eigene Klasse dafür schreiben oder wie muss ich das versehen?</p>
<pre><code class="language-cpp">Device-&gt;SetRenderState(D3DRS_ZENABLE,1);
Device-&gt;SetRenderState(D3DRS_ALPHABLENDENABLE,1);
Device-&gt;SetRenderState(D3DRS_CULLMODE,D3DCULL_CCW);
Device-&gt;SetRenderState(D3DRS_FILLMODE,D3DFILL_SOLID);
// ... noch 20 weitere States ...
</code></pre>
<p>Wenn ich Methode verlassen wird, sollen alle diese States rückgangig gemacht werden, die Methode wird an 8 verschiedenen Stellen verlassen. Wie würdet ihr das nun machen? Also ich kann mir beim besten Willen keine elegante Lösung mit RAII vorstellen.</p>
<p>Wenn RAII soo viel besser ist al try-catch-finally, wieso bieten dann modernere Sprachen wie C# und Java dieses Konstrukt an? Und das gerade obwohl diese Sprachen eigentlich viel weniger aufräumen müssen?</p>
<p>Und führt RAII nicht zugegebenermassen häufig dazu, dass man gezwungen wird, Code auseinanderzufrickeln, der eigentlich zusammengehört?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1884528</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1884528</guid><dc:creator><![CDATA[Ishildur]]></dc:creator><pubDate>Sun, 18 Apr 2010 11:11:29 GMT</pubDate></item><item><title><![CDATA[Reply to Try-Catch-Finally Ersatz on Sun, 18 Apr 2010 11:22:00 GMT]]></title><description><![CDATA[<blockquote>
<p>Soll ich nun für jede Eigenschaft die ich schreibe, eine eigene Klasse dafür schreiben oder wie muss ich das versehen?</p>
</blockquote>
<p>Du müsstest dir wahrscheinlich eine Klasse schreiben, die im Konstruktor die aktuellen RenderStates ausließt, speichert und danach die neuen RenderStates setzt.<br />
Im Destruktor der Klasse werden dann die gespeicherten RenderStates wieder gesetzt.<br />
Benutzen kannst du das ganze dann einfach folgendermaßen:</p>
<pre><code class="language-cpp">void myFunc()
{
  SetRenderStateClass state;
  /* Do something /*
} // Dtor von state wird automatisch ausgeführt
</code></pre>
<p>Wenn du jetzt sehr viele verschiedene Einstellungen brauchst, müsstest du natürlich entsprechend viele Klassen schreiben. Diesen Code müsstest du allerdings auch mit der try-catch-finally Methode schreiben, nur an einer anderen Stelle.</p>
<blockquote>
<p>Und führt RAII nicht zugegebenermassen häufig dazu, dass man gezwungen wird, Code auseinanderzufrickeln, der eigentlich zusammengehört?</p>
</blockquote>
<p>Nö, eigentlich nicht. RAII macht das Ressourcenmanagement nur übersichtlicher und ermöglicht exceptionsichere Programme in vielen Fällen erst.</p>
<p>...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1884537</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1884537</guid><dc:creator><![CDATA[...]]></dc:creator><pubDate>Sun, 18 Apr 2010 11:22:00 GMT</pubDate></item><item><title><![CDATA[Reply to Try-Catch-Finally Ersatz on Sun, 18 Apr 2010 11:34:14 GMT]]></title><description><![CDATA[<blockquote>
<p>Diesen Code müsstest du allerdings auch mit der try-catch-finally Methode schreiben, nur an einer anderen Stelle.</p>
</blockquote>
<p>Wie zum Beispiel in derjenigen Methode, zu welcher der Code gehört?</p>
<p>Also für mich sieht das einfach so aus, als müsste ich nun für jede Methode, in welcher ich in irgendeiner Form Resourcen alloziieren und oder sperren, resourcenbindende WinAPI Funktionen aufrufen, Semaphore anfassen oder States einer Statemaschine temporär ändern muss, eine entsprechende RAII Klasse schreiben. Mit anderen Worten, ich habe am ende tausende von RAII Klassen (keine Ahnung wie ich diese sinnvoll benennen soll), welche jeweils zwischen 5 - 6 Zeilen Code enthalten. Hoffentlich weiss ich dann zu jedem Zeitpunkt, welche RAII Klasse zu welcher Funktion gehört...</p>
<p>Mal ehrlich, das soll besser (eleganter) als try,catch,finally sein <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1884542</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1884542</guid><dc:creator><![CDATA[Ishildur]]></dc:creator><pubDate>Sun, 18 Apr 2010 11:34:14 GMT</pubDate></item><item><title><![CDATA[Reply to Try-Catch-Finally Ersatz on Sun, 18 Apr 2010 11:37:26 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>Auch dazu kann man sich spezialisierte Guard-Klassen basteln, die das im Destruktor machen - und zwar nur, falls sie nicht &quot;entschärft&quot; worden sind.</p>
</blockquote>
<p>Spezielle Guardklassen für jede Kleinigkeit finde ich fast so schlimm wie das Ersetzen jeder noch so trivialen Schleife durch Algorithmen und Funktoren.</p>
<p>Ich hatte <a href="http://www.c-plusplus.net/forum/viewtopic-var-p-is-1772254.html#1772254" rel="nofollow">hier</a> mal ein Safeguard-Makro gepostet; wenn dein Compiler schon <code>decltype</code> unterstützt, kannst du es benutzen. Es funktioniert so:</p>
<pre><code class="language-cpp">VertexBuffer* vb;
  IndexBuffer* ib;
  ...
  UCL_SAFEGUARD (vb, object-&gt;Lock (), object-&gt;Unlock ());
  UCL_SAFEGUARD (ib, object-&gt;Lock (), object-&gt;Unlock ());
  ...
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1884546</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1884546</guid><dc:creator><![CDATA[audacia]]></dc:creator><pubDate>Sun, 18 Apr 2010 11:37:26 GMT</pubDate></item><item><title><![CDATA[Reply to Try-Catch-Finally Ersatz on Sun, 18 Apr 2010 11:43:20 GMT]]></title><description><![CDATA[<blockquote>
<p>Also für mich sieht das einfach so aus, als müsste ich nun für jede Methode, in welcher ich in irgendeiner Form Resourcen alloziieren und oder sperren, resourcenbindende WinAPI Funktionen aufrufen, Semaphore anfassen oder States einer Statemaschine temporär ändern muss, eine entsprechende RAII Klasse schreiben. Mit anderen Worten, ich habe am ende tausende von RAII Klassen (keine Ahnung wie ich diese sinnvoll benennen soll), welche jeweils zwischen 5 - 6 Zeilen Code enthalten. Hoffentlich weiss ich dann zu jedem Zeitpunkt, welche RAII Klasse zu welcher Funktion gehört...</p>
</blockquote>
<p>Nein, du musst nur für jeden Resourcentyp (Speicher, Datei, Mutex, D3D-State usw.) eine Klasse schreiben, eine hübsche Eigenschaft von Klassen ist Wiederverwendbarkeit, d.h. du kannst diese dann in unterschiedlichen Funktionen nutzen (im Gegensatz zum Try-Catch-Finally-Konstrukt, welches du in jeder Funktion neu schreiben müsstest). Und jetzt sag nicht, du hast tausende unterschiedliche Resourcentypen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1884551</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1884551</guid><dc:creator><![CDATA[ipsec]]></dc:creator><pubDate>Sun, 18 Apr 2010 11:43:20 GMT</pubDate></item><item><title><![CDATA[Reply to Try-Catch-Finally Ersatz on Sun, 18 Apr 2010 11:46:32 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/8276">@audacia</a><br />
Vielen Dank für deinen Link, ich werde mir das mal ansehen.<br />
Was ist mit Conditional Cleanup?</p>
<pre><code class="language-cpp">void MyFunc(){
 try{
  // Hier werden einige Buffer gesperrt und eine CriticalSection geöffnet
  // Nun werden ziemlich viele Funktionen aufgerufen, von welchen viele
  // Exceptions werfen. Diese möchte ich aber nicht allesamt abfangen,
  // denn um die meissten kümmert sich eine höhere Instanz.
  // Zusätzlich hat es hier 7 oder 8 returns sowie auch noch einige throws
 }
 chatch(Exception &amp;e){
  // Hier kommt ein wenig Code hin der nur im Falle einer solchen Exception
  // ausgeführt wird, welche mich interessiert
 }
 finally{
  // Hier soll bspw. ein Buffer nur unter bestimmten Bedingungen
  // entsperrt werden, die Prüfung, ob die Bedingung war ist, muss 
  // aber in jedem Fall durchgeführt werden.
  // Die CriticalSection muss in jedem Fall verlassen werden.
 }
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1884553</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1884553</guid><dc:creator><![CDATA[Ishildur]]></dc:creator><pubDate>Sun, 18 Apr 2010 11:46:32 GMT</pubDate></item><item><title><![CDATA[Reply to Try-Catch-Finally Ersatz on Sun, 18 Apr 2010 11:56:30 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/16077">@ipsec</a></p>
<blockquote>
<p>Nein, du musst nur für jeden Resourcentyp (Speicher, Datei, Mutex, D3D-State usw.) eine Klasse schreiben,</p>
</blockquote>
<p>Nein nicht einie, sondern jeweils mindestens eine fürs Alloziieren sowie fürs Locken. (Methoden die IMHO klar zu einer Programmentität gehören werden wieder auseinandergerissen und in separate Programmteile zerlegt...)</p>
<blockquote>
<p>Und jetzt sag nicht, du hast tausende unterschiedliche Resourcentypen</p>
</blockquote>
<p>Ich nicht, die WinAPI und DirectX (die ich umfangreich benutze) schon...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1884554</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1884554</guid><dc:creator><![CDATA[Ishildur]]></dc:creator><pubDate>Sun, 18 Apr 2010 11:56:30 GMT</pubDate></item><item><title><![CDATA[Reply to Try-Catch-Finally Ersatz on Sun, 18 Apr 2010 15:30:14 GMT]]></title><description><![CDATA[<p>Ishildur schrieb:</p>
<blockquote>
<blockquote>
<p>Und jetzt sag nicht, du hast tausende unterschiedliche Resourcentypen</p>
</blockquote>
<p>Ich nicht, die WinAPI und DirectX (die ich umfangreich benutze) schon...</p>
</blockquote>
<p>Dafür gibt es dann verallgemeinernde Scope-Guards. Zum Beispiel kann man sich sowas basteln:</p>
<pre><code class="language-cpp">HDC dc = GetDC(hwnd);
ScopeGuard sg1(dc, &amp;ReleaseDC);

// ...

HPEN pen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
ScopeGuard sg2(pen, &amp;DeleteObject);

// ...

PAINTSTRUCT ps;
HDC dc2 = BeginPaint(hwnd, &amp;ps);
ScopeGuard sg3(dc2, boost::bind(&amp;EndPaint, hwnd, _1));

// usw.
</code></pre>
<p>Damit dürfte ein Großteil der Fälle abgedeckt sein. Und verständlich ist es m.E. auch. Ich weiß, am Ende des Scopes wird die entsprechende Funktion aufgerufen, von Auseinanderreißung kann man eigentlich nicht sprechen. Zumindest ist mir das lieber, als irgendwelche verschachtelten Try-Catch-Finally-Konstrukte.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1884570</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1884570</guid><dc:creator><![CDATA[ipsec]]></dc:creator><pubDate>Sun, 18 Apr 2010 15:30:14 GMT</pubDate></item><item><title><![CDATA[Reply to Try-Catch-Finally Ersatz on Sun, 18 Apr 2010 12:17:42 GMT]]></title><description><![CDATA[<p>Ishildur schrieb:</p>
<blockquote>
<p>Was ist mit Conditional Cleanup?</p>
</blockquote>
<p>Hast du fuer so eine Situation mal ein Beispiel?</p>
<p>Ansonsten: ist der conditional cleanup auch notwendig wenn du eine exception bekommst? Man kann aber im Prinzip mit lokalen Klassen arbeiten - dazu halt Makros um es zu vereinfachen.</p>
<blockquote>
<p>Nein nicht einie, sondern jeweils mindestens eine fürs Alloziieren sowie fürs Locken. (Methoden die IMHO klar zu einer Programmentität gehören werden wieder auseinandergerissen und in separate Programmteile zerlegt...)</p>
</blockquote>
<p>Dafuer gibt es generische Klassen.</p>
<p>Siehe zB das Makro von audacia.</p>
<blockquote>
<p>Ich nicht, die WinAPI und DirectX (die ich umfangreich benutze) schon...</p>
</blockquote>
<p>Und die werden alle komplett anders behandelt?<br />
Nein, die sind alle Schema F:<br />
du hast eine Alloc und eine Dealloc methode. Kann man also zusammen fassen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1884577</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1884577</guid><dc:creator><![CDATA[Shade Of Mine]]></dc:creator><pubDate>Sun, 18 Apr 2010 12:17:42 GMT</pubDate></item><item><title><![CDATA[Reply to Try-Catch-Finally Ersatz on Sun, 18 Apr 2010 12:26:52 GMT]]></title><description><![CDATA[<p>Ishildur schrieb:</p>
<blockquote>
<p>Wenn RAII soo viel besser ist al try-catch-finally, wieso bieten dann modernere Sprachen wie C# und Java dieses Konstrukt an? Und das gerade obwohl diese Sprachen eigentlich viel weniger aufräumen müssen?</p>
</blockquote>
<p>Sprachen mit Garbage Collector haben das Problem der nichtdeterministischen Zerstörung. Finalizers in Java können irgendwann oder gar nie aufgerufen werden, deshalb kann man dort schlecht Aufräumarbeiten hineinpacken. Immerhin geht C# mit <code>using</code> einen Schritt in Richtung RAII.</p>
<p>Ishildur schrieb:</p>
<blockquote>
<p>Und führt RAII nicht zugegebenermassen häufig dazu, dass man gezwungen wird, Code auseinanderzufrickeln, der eigentlich zusammengehört?</p>
</blockquote>
<p>Ich denke, es ist genau umgekehrt: Mit RAII kannst du gemeinsamen Code zusammenhalten. Im Konstruktor forderst du Ressourcen an, im Destruktor gibst du sie frei. Alles innerhalb der selben Klasse. Mit Try-Finally hingegen geschieht die Anforderung automatisch im Konstruktor, die Freigabe hingegen muss manuell auf Seiten des Anwenders erfolgen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1884587</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1884587</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Sun, 18 Apr 2010 12:26:52 GMT</pubDate></item><item><title><![CDATA[Reply to Try-Catch-Finally Ersatz on Sun, 18 Apr 2010 12:32:14 GMT]]></title><description><![CDATA[<p>Danke vielmals für die vielen Hinweise. Ich muss mich mal ein bissel durchwuseln und werde später meine Erfahrungen berichten und oder weitere Fragen stellen... <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/1884589</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1884589</guid><dc:creator><![CDATA[Ishildur]]></dc:creator><pubDate>Sun, 18 Apr 2010 12:32:14 GMT</pubDate></item></channel></rss>