<?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[Abstrakte Funktion in Konstruktor aufrufen]]></title><description><![CDATA[<p>Hi,</p>
<p>ich hab jetzt eine Abstrakte Klasse Hash. Diese hat unter anderem eine rein virtuelle Methoden HashLength. Diese moechte ich jetzt im Konstruktor verwenden um mit new Platz fuer den Hash zu reservieren. Kommt aber immer unresolved external.<br />
Also prinzipiel versteh ich schon warum das ned geht, weil er ja versucht die Methode Hash::HashLength aufzurufen. Aber ich habe mir gedacht da es ja sowieso eine abstrakte Klasse ist und dies eine rein virtuele Methode ist geht das da ich die ja in der abgeleiteten Klasse impelementiere. Ich hab mir jetzt so geholfen das ich nen Konstruktor mit der Size als uebergabe Parameter hab fuer Hash.</p>
<p>Jetzt ist die Frage ob das mit der Methode einfach nicht geht oder ob ich was anders machen muss.</p>
<p>Gruess C0de4Fun</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/282042/abstrakte-funktion-in-konstruktor-aufrufen</link><generator>RSS for Node</generator><lastBuildDate>Sun, 23 Aug 2026 10:34:24 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/282042.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 12 Feb 2011 17:05:36 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Abstrakte Funktion in Konstruktor aufrufen on Sat, 12 Feb 2011 17:05:36 GMT]]></title><description><![CDATA[<p>Hi,</p>
<p>ich hab jetzt eine Abstrakte Klasse Hash. Diese hat unter anderem eine rein virtuelle Methoden HashLength. Diese moechte ich jetzt im Konstruktor verwenden um mit new Platz fuer den Hash zu reservieren. Kommt aber immer unresolved external.<br />
Also prinzipiel versteh ich schon warum das ned geht, weil er ja versucht die Methode Hash::HashLength aufzurufen. Aber ich habe mir gedacht da es ja sowieso eine abstrakte Klasse ist und dies eine rein virtuele Methode ist geht das da ich die ja in der abgeleiteten Klasse impelementiere. Ich hab mir jetzt so geholfen das ich nen Konstruktor mit der Size als uebergabe Parameter hab fuer Hash.</p>
<p>Jetzt ist die Frage ob das mit der Methode einfach nicht geht oder ob ich was anders machen muss.</p>
<p>Gruess C0de4Fun</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2020187</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2020187</guid><dc:creator><![CDATA[C0de4Fun]]></dc:creator><pubDate>Sat, 12 Feb 2011 17:05:36 GMT</pubDate></item><item><title><![CDATA[Reply to Abstrakte Funktion in Konstruktor aufrufen on Sat, 12 Feb 2011 17:34:25 GMT]]></title><description><![CDATA[<p><a href="http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.5" rel="nofollow">http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.5</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2020202</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2020202</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Sat, 12 Feb 2011 17:34:25 GMT</pubDate></item><item><title><![CDATA[Reply to Abstrakte Funktion in Konstruktor aufrufen on Sat, 12 Feb 2011 18:11:35 GMT]]></title><description><![CDATA[<p>C++ ist schon komisch... Einerseits setzt ein &quot;schöner, echter&quot; C++-Code RAII voraus, was Verlagerung der Funktionalität in die Konstruktoren bzw. Destruktoren bedeutet. Andererseits werden genau da andere Mittel um &quot;schicken&quot; Code zu erzeugen, namentlich Exceptions oder Vererbung, ausser Kraft gesetzt. Will man diese doch noch verwenden müssen auf absolut unpassende und hässliche Verrenkungen getan werden (init/close), was aber wieder RAII verhindert. Nur um wieder einen Widerspruch der Sprache C++ aufzuzeigen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2020212</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2020212</guid><dc:creator><![CDATA[sprachbarriere]]></dc:creator><pubDate>Sat, 12 Feb 2011 18:11:35 GMT</pubDate></item><item><title><![CDATA[Reply to Abstrakte Funktion in Konstruktor aufrufen on Sat, 12 Feb 2011 18:24:52 GMT]]></title><description><![CDATA[<p>Exceptions in Konstruktoren sind üblich und schaden nicht. Im Destruktor hast du natürlich auch Funktionalität. Aber man kann auf Destruktionsfehler eben oft schlecht reagieren.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2020219</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2020219</guid><dc:creator><![CDATA[fdfdg]]></dc:creator><pubDate>Sat, 12 Feb 2011 18:24:52 GMT</pubDate></item><item><title><![CDATA[Reply to Abstrakte Funktion in Konstruktor aufrufen on Sat, 12 Feb 2011 18:25:16 GMT]]></title><description><![CDATA[<p>sprachbarriere schrieb:</p>
<blockquote>
<p>[...]</p>
</blockquote>
<p>Bitte was? Was für einen Widerspruch? Bitte keine zusammen gereimte Verallgemeinerungen. Konkrete Beispiele.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2020220</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2020220</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Sat, 12 Feb 2011 18:25:16 GMT</pubDate></item><item><title><![CDATA[Reply to Abstrakte Funktion in Konstruktor aufrufen on Sat, 12 Feb 2011 20:15:44 GMT]]></title><description><![CDATA[<p>Prämissen:</p>
<ol>
<li>C++ und RAII passen gut zusammen (vgl. Stroustrup)</li>
<li>Bei einem Fehler soll eine Ausnahme geworfen werden</li>
</ol>
<p>Als man <code>std::file</code> entwarf, gab es beide Prämissen noch nicht in dieser Form, daher sind sie erst nachträglich hinzuimplementiert worden. Ich kritisiere aber noch nicht die veraltete Standardbibliothek (kommt unten), sondern betrachte als Beispiel eine <code>file</code> -Klasse in modernem C++.</p>
<p>Aus 1. folgt: Konstruktor öffnet die Datei, Destruktor schliesst die Datei.<br />
Aus 2. folgt: Bei irgend einem Fehler beim Öffnen/Schliessen der Datei wird eine exception geworfen.<br />
Schlussfolgerung: Der Destruktor muss manchmal eine Ausnahme werfen.</p>
<p>Dass das nicht geht ist dir hoffentlich klar. Ich gehe einen Schritt weiter:</p>
<p>fdfdg schrieb:</p>
<blockquote>
<p>man kann auf Destruktionsfehler eben oft schlecht reagieren.</p>
</blockquote>
<p>Das ist so, da kann C++ direkt nichts dafür.<br />
Der Widerspruch liegt in den Prämissen zugrunde, d.h 1 und 2 sind zueinander widersprüchlich. Ist der Destruktor <em>nicht</em> dafür zuständig, Code auszuführen, entsteht das Problem nicht, ebenso wie wenn es keine Ausnahmen geben würde. Wenn somit die Paradigmen 1 und 2 einander widersprechen, widersprechen sich die Paradigmen von C++ und somit in gewissem Masse auch C++ selbst.</p>
<p>Die Argumentation lässt sich leicht auch virtuelle Funktionen und RAII übertragen; wenn der Konstruktor uneingeschränkt Initialisierungen vornehmen soll und gleichzeitig eingeschränkt ist (er kann keine abgeleiteten Funktionen aufrufen), dann ist etwas faul.</p>
<p>Die versprochene Kritik an der Standardbibliothek:</p>
<pre><code class="language-cpp">std::string s; // RAII: s ist fertig initialisiert und kann verwendet werden
std::cin &gt;&gt; s; // stdc++: s wird gleich nochmal initialisiert, hä???
</code></pre>
<p>RAII wäre folgendes:</p>
<pre><code class="language-cpp">std::string s(std::cin.read&lt;std::string&gt;()); // Kopierkonstruktor
</code></pre>
<p>Wie das Paradigma heisst, welches hier angewendet wird, weiss ich nicht, vielleicht &quot;<em>Operatorenüberladung um jeden Preis</em>&quot;. Jedenfalls kommt es nicht mit &quot;<em>ein Objekt wird nur einmal initialisiert</em>&quot; zurecht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2020251</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2020251</guid><dc:creator><![CDATA[sprachbarriere]]></dc:creator><pubDate>Sat, 12 Feb 2011 20:15:44 GMT</pubDate></item><item><title><![CDATA[Reply to Abstrakte Funktion in Konstruktor aufrufen on Sat, 12 Feb 2011 20:52:50 GMT]]></title><description><![CDATA[<p>sprachbarriere schrieb:</p>
<blockquote>
<p>...sondern betrachte als Beispiel eine <code>file</code> -Klasse in modernem C++.</p>
</blockquote>
<p>Was für eine file Klasse? Verstehe gerade nicht ganz wovon du redest. FILE ist nicht C++.</p>
<p>sprachbarriere schrieb:</p>
<blockquote>
<p>Aus 1. folgt: Konstruktor öffnet die Datei, Destruktor schliesst die Datei.</p>
</blockquote>
<p>Nicht wirklich. Kleines Beispiel:</p>
<pre><code class="language-cpp">std::auto_ptr&lt;int&gt; pi(new int(4));
</code></pre>
<p>Da wird im Konstruktor von auto_ptr nirgends irgend eine Ressource (in dem Fall also Speicher) alloziert. Das geschieht durch den Aufruf des new-operators. Allerdings initialisiere ich den auto_ptr mit dem zurückgegebenen pointer.</p>
<p>sprachbarriere schrieb:</p>
<blockquote>
<p>Aus 2. folgt: Bei irgend einem Fehler beim Öffnen/Schliessen der Datei wird eine exception geworfen.<br />
Schlussfolgerung: Der Destruktor muss manchmal eine Ausnahme werfen.</p>
</blockquote>
<p>Nicht der Destruktor wirft die Exception, sondern ggf. der code der hier ausgeführt wird. Das ist aber ja auch kein Problem, mann muss entsprechend nur dafür sorgen, dass der Destruktor die exception nicht propagiert.<br />
Möglichkeiten hat man ja genug (anderen exception handler setzen, Exception einfach schlucken, abort aufrufen etc.). Muss im Destruktor code ausgeführt werden, der möglicherweise eine exception wirft, dann bietet man i.d.R. ein öffentlich Methode an die diesen code ebenfalls ausführt um dem Benutzer die Möglichkeit zu geben, nach eigenem Gutdünken auf diese exception zu reagieren.</p>
<p>sprachbarriere schrieb:</p>
<blockquote>
<p>Die Argumentation lässt sich leicht auch virtuelle Funktionen und RAII übertragen; wenn der Konstruktor uneingeschränkt Initialisierungen vornehmen soll und gleichzeitig eingeschränkt ist (er kann keine abgeleiteten Funktionen aufrufen), dann ist etwas faul.</p>
</blockquote>
<p>Erstmal: was hat das jetzt mit RAII zu tun? Seh ich keinen Zusammenhang.<br />
Wie soll denn während der Konstruktion eines Objektes auf noch nicht konstruirte member zugegriffen werden? Die Reihenfolge der Konstruktoren-Aufrufe ist dir hoffentlich klar. Dann dürfte auch klar sein, warum zum Zeitpunkt der Konstruktion des Basisklassenteils eines Objekts das Objekt auch nur als Typ dieser Basisklasse behandelt werden kann (und tatsächlich zu dem Zeitpunkt auch eins ist - alles andere wurde ja noch nicht konstruiert).</p>
<p>sprachbarriere schrieb:</p>
<blockquote>
<p>Die versprochene Kritik an der Standardbibliothek:</p>
<pre><code class="language-cpp">std::string s; // RAII: s ist fertig initialisiert und kann verwendet werden
std::cin &gt;&gt; s; // stdc++: s wird gleich nochmal initialisiert, hä???
</code></pre>
</blockquote>
<p>Wieso wird bei std::cin&gt;&gt;s der string nochmal initialisiert. Wird er nicht.</p>
<p>Grüsse</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2020268</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2020268</guid><dc:creator><![CDATA[inter2k3]]></dc:creator><pubDate>Sat, 12 Feb 2011 20:52:50 GMT</pubDate></item><item><title><![CDATA[Reply to Abstrakte Funktion in Konstruktor aufrufen on Sat, 12 Feb 2011 20:56:11 GMT]]></title><description><![CDATA[<p>Hmm joa stimmt das kenn ich doch das erst der Basis-Konstruktor und dann von der Abgeleiteten Klasse aufgerufen wird ( und beim Destruktor anders rum). Dann is des au klar warum das ned geht.</p>
<p>Ich danke euch.<br />
Greetz C0de4Fun</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2020272</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2020272</guid><dc:creator><![CDATA[C0de4Fun]]></dc:creator><pubDate>Sat, 12 Feb 2011 20:56:11 GMT</pubDate></item><item><title><![CDATA[Reply to Abstrakte Funktion in Konstruktor aufrufen on Sat, 12 Feb 2011 21:36:37 GMT]]></title><description><![CDATA[<p>inter2k3 schrieb:</p>
<blockquote>
<p>Was für eine file Klasse? Verstehe gerade nicht ganz wovon du redest. FILE ist nicht C++.</p>
</blockquote>
<p>Mein Fehler, gemeint war <code>std::fstream</code> . Aber das hindert uns nicht daran, das Gleiche als <code>file</code> zu implementieren.</p>
<p>inter2k3 schrieb:</p>
<blockquote>
<p>Kleines Beispiel:</p>
<pre><code class="language-cpp">std::auto_ptr&lt;int&gt; pi(new int(4));
</code></pre>
<p>Da wird im Konstruktor von auto_ptr nirgends irgend eine Ressource (in dem Fall also Speicher) alloziert.</p>
</blockquote>
<p>Gegenbeispiel:</p>
<pre><code class="language-cpp">std::vector&lt;int&gt;(4);
</code></pre>
<p>Tenor: Kommt auf den Kontext drauf an.<br />
Mein Beispiel ist nicht aus der Luft gegriffen, genau die Klasse <code>file</code> wird auch in der englischen (und deutschen) Wikipedia unter <a href="http://de.wikipedia.org/wiki/RAII" rel="nofollow">RAII</a> angeführt.</p>
<p>inter2k3 schrieb:</p>
<blockquote>
<p>Das ist aber ja auch kein Problem, mann muss entsprechend nur dafür sorgen, dass der Destruktor die exception nicht propagiert.<br />
Möglichkeiten hat man ja genug (anderen exception handler setzen, Exception einfach schlucken, abort aufrufen etc.).</p>
</blockquote>
<p>Das sind die von mir im ersten Post als &quot;unpassende und hässliche[n] Verrenkungen&quot; bezeichnete Gegenmassnahmen. Nicht, dass es nicht möglich wäre, einen Workaround auszuwählen, aber keiner kann von sich behaupten, rein auf Exception-Denken begründet zu sein.</p>
<p>inter2k3 schrieb:</p>
<blockquote>
<p>sprachbarriere schrieb:</p>
<blockquote>
<p>Die Argumentation lässt sich leicht auch virtuelle Funktionen und RAII übertragen [...]</p>
</blockquote>
<p>Erstmal: was hat das jetzt mit RAII zu tun?</p>
</blockquote>
<p>Du siehst meinen Punkt nicht. Die Initialisierungsreihenfolge kommt aus technischen Überlegungen zustande. Was soll zuerst erledigt werden. C++ hat sich für den ganzen Konstruktor entschieden (m.E. ist das auch richtig so). Nun muss der Konstruktor nicht nur Standardwerte setzen, sondern manchmal hochkomplexe Ressourcen anfordern. Dass genau dieser wichtige Teil Einschränkungen unterlegen ist, was alle möglichen Spezialisierungen betrifft, gefällt mir überhaupt nicht. Weil das in der Praxis zutage tritt, gibt es selbstverständlich wieder unzählige Workarounds, händisch übergebene Funktionspointer, Mehrfachvererbung um einen Member zu übergeben, aber wieder kann nichts davon behaupten, intuitiv und mit dem Konzept der virtuellen Funktionen übereinstimmendend zu sein.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2020290</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2020290</guid><dc:creator><![CDATA[sprachbarriere]]></dc:creator><pubDate>Sat, 12 Feb 2011 21:36:37 GMT</pubDate></item><item><title><![CDATA[Reply to Abstrakte Funktion in Konstruktor aufrufen on Sat, 12 Feb 2011 22:29:13 GMT]]></title><description><![CDATA[<p>sprachbarriere schrieb:</p>
<blockquote>
<p>inter2k3 schrieb:</p>
<blockquote>
<p>Kleines Beispiel:</p>
<pre><code class="language-cpp">std::auto_ptr&lt;int&gt; pi(new int(4));
</code></pre>
<p>Da wird im Konstruktor von auto_ptr nirgends irgend eine Ressource (in dem Fall also Speicher) alloziert.</p>
</blockquote>
<p>Gegenbeispiel:</p>
<pre><code class="language-cpp">std::vector&lt;int&gt;(4);
</code></pre>
</blockquote>
<p>Findest du auch ein Beispiel, bei dem man nicht direkt &quot;selbst Schuld&quot; schreien will?</p>
<blockquote>
<p>Dass genau dieser wichtige Teil Einschränkungen unterlegen ist, was alle möglichen Spezialisierungen betrifft, gefällt mir überhaupt nicht. Weil das in der Praxis zutage tritt, gibt es selbstverständlich wieder unzählige Workarounds, händisch übergebene Funktionspointer, Mehrfachvererbung um einen Member zu übergeben, aber wieder kann nichts davon behaupten, intuitiv und mit dem Konzept der virtuellen Funktionen übereinstimmendend zu sein.</p>
</blockquote>
<p>Hast du ein Beispiel?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2020315</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2020315</guid><dc:creator><![CDATA[Michael E.]]></dc:creator><pubDate>Sat, 12 Feb 2011 22:29:13 GMT</pubDate></item></channel></rss>