<?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[Rein virtuelle Funktion in Konstruktor]]></title><description><![CDATA[<p>Hallo,</p>
<p>angenommen ich habe zwei Klassen</p>
<pre><code>class B
{
    B() { f(); }
    virtual void f() = 0;
    ...
}
</code></pre>
<p>und</p>
<pre><code>class D : public B
{
    D() : B() { // initialisiere irgendwelche data members }
    void f();
    ...
}
</code></pre>
<p>wobei f() irgendwie auf data members von B zugreift.</p>
<p>Wenn ich das so richtig sehe, kann der Konstruktor von D so nicht funktionieren, da zuerst der Konstruktor von B aufgerufen wird, der f aufruft und f greift dann auf data members von D zu, die erst noch initialisiert werden.</p>
<p>Kann mir jemand sagen, ob das so stimmt und, wenn ja, welches der beste Workaround ist?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/239822/rein-virtuelle-funktion-in-konstruktor</link><generator>RSS for Node</generator><lastBuildDate>Tue, 22 Sep 2026 06:52:29 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/239822.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 28 Apr 2009 13:33:26 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Rein virtuelle Funktion in Konstruktor on Tue, 28 Apr 2009 13:33:26 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>angenommen ich habe zwei Klassen</p>
<pre><code>class B
{
    B() { f(); }
    virtual void f() = 0;
    ...
}
</code></pre>
<p>und</p>
<pre><code>class D : public B
{
    D() : B() { // initialisiere irgendwelche data members }
    void f();
    ...
}
</code></pre>
<p>wobei f() irgendwie auf data members von B zugreift.</p>
<p>Wenn ich das so richtig sehe, kann der Konstruktor von D so nicht funktionieren, da zuerst der Konstruktor von B aufgerufen wird, der f aufruft und f greift dann auf data members von D zu, die erst noch initialisiert werden.</p>
<p>Kann mir jemand sagen, ob das so stimmt und, wenn ja, welches der beste Workaround ist?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1702645</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1702645</guid><dc:creator><![CDATA[ingobulla]]></dc:creator><pubDate>Tue, 28 Apr 2009 13:33:26 GMT</pubDate></item><item><title><![CDATA[Reply to Rein virtuelle Funktion in Konstruktor on Tue, 28 Apr 2009 15:06:00 GMT]]></title><description><![CDATA[<p>ingobulla schrieb:</p>
<blockquote>
<p>Wenn ich das so richtig sehe, kann der Konstruktor von D so nicht funktionieren, da zuerst der Konstruktor von B aufgerufen wird, der f aufruft und f greift dann auf data members von D zu, die erst noch initialisiert werden.</p>
</blockquote>
<p>Edit:<br />
<a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/904">@Bashar</a>: &quot;pure virtual&quot; hatte ich übersehen.</p>
<p>Zur Ergänzung aber noch eine Sache: Ein Konstruktor &quot;sieht&quot; immer die virtuellen Funktionen, von der aktuellen Klasse bis zu den Basisklassen.</p>
<p>Wenn du eine Hierarchie A-&gt;B-&gt;C (A ist die unterste Basisklasse) hast, und du ein Element von Typ C anlegst, wird erst der A-Anteil, dann der B-Anteil und zu guterletzt der C-Anteil konstruiert. Das heißt auch das der Konstruktor von B beim Aufruf einer virtuellen Funktion nur A und B betrachtet (Da zu dem Zeitpunkt nur A und B bekannt ist).</p>
<p>ingobulla schrieb:</p>
<blockquote>
<p>Kann mir jemand sagen, ob das so stimmt und, wenn ja, welches der beste Workaround ist?</p>
</blockquote>
<p>Wenn man nicht die Logik durch überdenken des Konzeptes anpassen kann*, ist der einzige mir auf Anhieb einfallende Weg der, die Initialisierung auf einen späteren Zeitpunkt zu verschieben. In einem solchen Fall gehe ich persönlich dazu über den Konstruktor nicht-public zu machen, sondern über Fabrikmethoden (z.B. eine statische Funktion die ein Objekt erzeugt) zu verwenden. Letztere kann nach dem Konstruktoraufruf noch weitere Initialisierungen durchführen.</p>
<p>* Nachtrag: In der Regel versuche ich die Abhängigkeiten auch bei Vererbung so gering wie möglich zu halten (z.B. in dem man dem Konstruktor der Basisklasse entsprechende Parameter übergibt, und nicht den Standardkonstruktor verwendet; was mit der Verwendung der Initialisierungsliste ja geht).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1702660</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1702660</guid><dc:creator><![CDATA[asc]]></dc:creator><pubDate>Tue, 28 Apr 2009 15:06:00 GMT</pubDate></item><item><title><![CDATA[Reply to Rein virtuelle Funktion in Konstruktor on Tue, 28 Apr 2009 14:45:47 GMT]]></title><description><![CDATA[<p>asc schrieb:</p>
<blockquote>
<p>ingobulla schrieb:</p>
<blockquote>
<p>Wenn ich das so richtig sehe, kann der Konstruktor von D so nicht funktionieren, da zuerst der Konstruktor von B aufgerufen wird, der f aufruft und f greift dann auf data members von D zu, die erst noch initialisiert werden.</p>
</blockquote>
<p>Genau.</p>
</blockquote>
<p>Falsch, f wird zu diesem Zeitpunkt zu B::f aufgelöst (12.7§3), was dir undefiniertes Verhalten (bzw. einen Programmabruch mit der Meldung &quot;pure virtual function called&quot;) einbringt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1702691</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1702691</guid><dc:creator><![CDATA[Bashar]]></dc:creator><pubDate>Tue, 28 Apr 2009 14:45:47 GMT</pubDate></item><item><title><![CDATA[Reply to Rein virtuelle Funktion in Konstruktor on Tue, 28 Apr 2009 15:07:30 GMT]]></title><description><![CDATA[<p>Bashar schrieb:</p>
<blockquote>
<p>Falsch,...</p>
</blockquote>
<p>Stimmt, war zu schnell und habe weder das pure-virtual gesehen, noch eine sinnvolle Erklärung geliefert (Oben geändert).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1702700</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1702700</guid><dc:creator><![CDATA[asc]]></dc:creator><pubDate>Tue, 28 Apr 2009 15:07:30 GMT</pubDate></item><item><title><![CDATA[Reply to Rein virtuelle Funktion in Konstruktor on Tue, 28 Apr 2009 16:21:52 GMT]]></title><description><![CDATA[<p>Bashar schrieb:</p>
<blockquote>
<p>Falsch, f wird zu diesem Zeitpunkt zu B::f aufgelöst (12.7§3), was dir undefiniertes Verhalten (bzw. einen Programmabruch mit der Meldung &quot;pure virtual function called&quot;) einbringt.</p>
</blockquote>
<p>Auf was bezieht sich denn (12.7§3)?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1702731</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1702731</guid><dc:creator><![CDATA[ingobulla]]></dc:creator><pubDate>Tue, 28 Apr 2009 16:21:52 GMT</pubDate></item><item><title><![CDATA[Reply to Rein virtuelle Funktion in Konstruktor on Tue, 28 Apr 2009 16:24:28 GMT]]></title><description><![CDATA[<p>Auf den C++-Standard, ISO/IEC 14882:1998. Abschnitt 12.7, Absatz 3 <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/1702733</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1702733</guid><dc:creator><![CDATA[Bashar]]></dc:creator><pubDate>Tue, 28 Apr 2009 16:24:28 GMT</pubDate></item><item><title><![CDATA[Reply to Rein virtuelle Funktion in Konstruktor on Tue, 28 Apr 2009 17:35:15 GMT]]></title><description><![CDATA[<p>asc schrieb:</p>
<blockquote>
<p>Bashar schrieb:</p>
<blockquote>
<p>Falsch,...</p>
</blockquote>
<p>Stimmt, war zu schnell und habe weder das pure-virtual gesehen, noch eine sinnvolle Erklärung geliefert (Oben geändert).</p>
</blockquote>
<p>Das hat mit pure-virtual nix zu tun, in B::B wird niemals D::f aufgerufen werden. Ob B::f dabei pure ist oder nicht spielt keine Rolle.<br />
Wenn es nicht pure wäre, würde es halt keinen Fehler geben, und es würde B::f aufgerufen (was es ja dann geben muss, weil B::f ja implementiert sein muss, wenn es nicht pure ist).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1702770</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1702770</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 28 Apr 2009 17:35:15 GMT</pubDate></item><item><title><![CDATA[Reply to Rein virtuelle Funktion in Konstruktor on Fri, 22 May 2009 13:19:26 GMT]]></title><description><![CDATA[<p>asc schrieb:</p>
<blockquote>
<p>Wenn man nicht die Logik durch überdenken des Konzeptes anpassen kann, ist der einzige mir auf Anhieb einfallende Weg der, die Initialisierung auf einen späteren Zeitpunkt zu verschieben. In einem solchen Fall gehe ich persönlich dazu über den Konstruktor nicht-public zu machen, sondern über Fabrikmethoden (z.B. eine statische Funktion die ein Objekt erzeugt) zu verwenden. Letztere kann nach dem Konstruktoraufruf noch weitere Initialisierungen durchführen.</p>
</blockquote>
<p>Wenn ich das richtig verstehe, wuerde das dann wie folgt aussehen:</p>
<pre><code class="language-cpp">class D : public B
{
    D() : B() { // initialisiere irgendwelche data members }
    void f();
public:
    static D* create() {
        D* d = new D();
        d-&gt;f();
        return d;
    }
    ...
}
</code></pre>
<p>Ist das so gemeint? Mein Problem hier ist, dass, wenn ich aus B weitere Klassen ableite, die von der Struktur wie D sind, ich in deren Fabrikmethode immer dran denke muss, f() aufzurufen. Daher wuerde ich den Aufruf von f() lieber irgendwie in B behalten.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1703135</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1703135</guid><dc:creator><![CDATA[ingobulla]]></dc:creator><pubDate>Fri, 22 May 2009 13:19:26 GMT</pubDate></item><item><title><![CDATA[Reply to Rein virtuelle Funktion in Konstruktor on Wed, 29 Apr 2009 12:51:37 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">struct BBase
{
    virtual void f (void) = 0;
};

template &lt;class C&gt;
    struct B : BBase
{
    static C* create (void)
    {
        std::auto_ptr &lt;C&gt; result (new C);
        result-&gt;f ();
        return result.release ();
    }
};

struct C : B &lt;C&gt;
{
    void f (void) { ... }
    C (void) { ...}
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1703140</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1703140</guid><dc:creator><![CDATA[audacia]]></dc:creator><pubDate>Wed, 29 Apr 2009 12:51:37 GMT</pubDate></item><item><title><![CDATA[Reply to Rein virtuelle Funktion in Konstruktor on Wed, 29 Apr 2009 12:57:07 GMT]]></title><description><![CDATA[<p>ingobulla schrieb:</p>
<blockquote>
<p>Ist das so gemeint? Mein Problem hier ist, dass, wenn ich aus B weitere Klassen ableite, die von der Struktur wie D sind, ich in deren Fabrikmethode immer dran denke muss, f() aufzurufen.</p>
</blockquote>
<p>Ohne deinen Fall genau zu kennen, kann ich dir nur sagen, das es nur 2 Lösungsansätze gibt:<br />
a) Die Basisklasse über dessen Konstruktor gleich richtig initialisieren (wenn möglich)<br />
b) Über Fabrikmethoden (Und ja, dann kannst du f() auch vergessen)</p>
<p>In der Regel würde ich a) ohnehin b) vorziehen.</p>
<p>Edit: Okay, das &quot;Curiously Recurring Template Pattern&quot; habe ich tatsächlich nicht berücksichtigt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1703143</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1703143</guid><dc:creator><![CDATA[asc]]></dc:creator><pubDate>Wed, 29 Apr 2009 12:57:07 GMT</pubDate></item><item><title><![CDATA[Reply to Rein virtuelle Funktion in Konstruktor on Wed, 29 Apr 2009 13:05:21 GMT]]></title><description><![CDATA[<p>audacia schrieb:</p>
<blockquote>
<pre><code class="language-cpp">struct BBase
{
    virtual void f (void) = 0;
};

template &lt;class C&gt;
    struct B : BBase
{
    static C* create (void)
    {
        std::auto_ptr &lt;C&gt; result (new C);
        result-&gt;f ();
        return result.release ();
    }
};

struct C : B &lt;C&gt;
{
    void f (void) { ... }
    C (void) { ...}
};
</code></pre>
</blockquote>
<p>Das scheint mir die Loesung des Problems. Hat diese Art von Fabrikmethoden-Konstrukt eigentlich einen Namen?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1703147</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1703147</guid><dc:creator><![CDATA[ingobulla]]></dc:creator><pubDate>Wed, 29 Apr 2009 13:05:21 GMT</pubDate></item><item><title><![CDATA[Reply to Rein virtuelle Funktion in Konstruktor on Wed, 29 Apr 2009 13:37:35 GMT]]></title><description><![CDATA[<p>ingobulla schrieb:</p>
<blockquote>
<p>Das scheint mir die Loesung des Problems. Hat diese Art von Fabrikmethoden-Konstrukt eigentlich einen Namen?</p>
</blockquote>
<p>Dieses Templatekonstrukt nennt sich &quot;Curiously Recurring Template Pattern&quot; (Kurios weil es sich auf den Datentyp der Kindklasse bezieht). Dies ist aber unabhängig davon ob man es als Factory oder für andere Dinge verwendet.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1703162</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1703162</guid><dc:creator><![CDATA[asc]]></dc:creator><pubDate>Wed, 29 Apr 2009 13:37:35 GMT</pubDate></item><item><title><![CDATA[Reply to Rein virtuelle Funktion in Konstruktor on Wed, 29 Apr 2009 14:05:31 GMT]]></title><description><![CDATA[<p>asc schrieb:</p>
<blockquote>
<p>(Kurios weil es sich auf den Datentyp der Kindklasse bezieht).</p>
</blockquote>
<p><a href="http://en.wikipedia.org/wiki/Curiously_Recurring_Template_Pattern" rel="nofollow">Wikipedia</a> ist anderer Meinung:</p>
<p>Wikipedia schrieb:</p>
<blockquote>
<p>The name of this idiom was coined by Jim Coplien[1], who had observed it in some of the earliest C++ template code.</p>
</blockquote>
<p>Ich würde es mit &quot;seltsamerweise immer wieder auftauchendes Template-Pattern&quot; übersetzen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1703176</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1703176</guid><dc:creator><![CDATA[audacia]]></dc:creator><pubDate>Wed, 29 Apr 2009 14:05:31 GMT</pubDate></item><item><title><![CDATA[Reply to Rein virtuelle Funktion in Konstruktor on Wed, 29 Apr 2009 16:32:16 GMT]]></title><description><![CDATA[<p>audacia schrieb:</p>
<blockquote>
<p>asc schrieb:</p>
<blockquote>
<p>(Kurios weil es sich auf den Datentyp der Kindklasse bezieht).</p>
</blockquote>
<p><a href="http://en.wikipedia.org/wiki/Curiously_Recurring_Template_Pattern" rel="nofollow">Wikipedia</a> ist anderer Meinung:</p>
</blockquote>
<p>Gerade mit dem von dir angegebenen Zitat kann ich keinen Widerspruch zu meiner Beschreibung sehen. Zudem fand ich die Erklärung im &quot;C++ Templates&quot; Buch deutlich besser.</p>
<p>Wikipedia schrieb:</p>
<blockquote>
<p>Ich würde es mit &quot;seltsamerweise immer wieder auftauchendes Template-Pattern&quot; übersetzen.</p>
</blockquote>
<p>&quot;Kurios wiederholendes Templatepattern&quot; hört sich für mich persönlich besser an.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1703258</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1703258</guid><dc:creator><![CDATA[asc]]></dc:creator><pubDate>Wed, 29 Apr 2009 16:32:16 GMT</pubDate></item><item><title><![CDATA[Reply to Rein virtuelle Funktion in Konstruktor on Wed, 29 Apr 2009 17:15:53 GMT]]></title><description><![CDATA[<p>asc schrieb:</p>
<blockquote>
<p>Gerade mit dem von dir angegebenen Zitat kann ich keinen Widerspruch zu meiner Beschreibung sehen.</p>
</blockquote>
<p>Das Zitat im Kontext des Satzes selbst macht deutlich, daß die Bezeichnung &quot;Curiously Recurring Template Pattern&quot; nicht deskriptiv ist; sie bezieht sich nicht auf das Pattern selbst, sondern auf das Phänomen desselben.</p>
<p>asc schrieb:</p>
<blockquote>
<p>Zudem fand ich die Erklärung im &quot;C++ Templates&quot; Buch deutlich besser.</p>
</blockquote>
<p>Dann laß mal sehen.</p>
<p>asc schrieb:</p>
<blockquote>
<p>&quot;Kurios wiederholendes Templatepattern&quot; hört sich für mich persönlich besser an.</p>
</blockquote>
<p>Tatsächlich? Mit meinem Sprachverständnis (und vermutlich auch mit der deutschen Grammatik) ist dieser Satz nicht so recht vereinbar <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="😉"
    /> Was soll, von der Unbekanntheit des englischen Originals ausgehend, &quot;kurios wiederholendes Pattern&quot; denn aussagen? Fehlt bei &quot;wiederholen&quot; nicht ein Objekt?<br />
Übrigens ist LEO bei &quot;<a href="http://dict.leo.org/ende?lp=ende&amp;p=thMx..&amp;search=curiously" rel="nofollow">couriously</a>&quot; und &quot;<a href="http://dict.leo.org/ende?lp=ende&amp;lang=de&amp;searchLoc=0&amp;cmpType=relaxed&amp;sectHdr=on&amp;spellToler=on&amp;chinese=both&amp;pinyin=diacritic&amp;search=recur&amp;relink=on" rel="nofollow">recur</a>&quot; recht eindeutig: weder &quot;kurios&quot; noch &quot;wiederholend&quot; sind adäquate Übertragungen.</p>
<p>Außerdem finde ich die Bezeichnung &quot;Curiously Recurring Template Pattern&quot; ohnehin meidenswert, da sie nicht deskriptiv ist. Obiges Codebeispiel kann ebensogut als Mixin eingeordnet werden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1703278</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1703278</guid><dc:creator><![CDATA[audacia]]></dc:creator><pubDate>Wed, 29 Apr 2009 17:15:53 GMT</pubDate></item></channel></rss>