<?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[CRTP bei Factory-Methoden mit verschiedener Signatur]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich habe zwei Klassen (hier nur Auszuege gezeigt)</p>
<pre><code class="language-cpp">class Prob_Nd 
{
protected:
	Prob_Nd();
	void alloc_log_subst_prob();
};
</code></pre>
<p>und</p>
<pre><code class="language-cpp">class Rev_Tip_Nd : public Prob_Nd
{
private:
	Rev_Tip_Nd(Rev_Tree* tr, Rev_Tip_NC* node_contnr, string nucl_seq, boost::variant&lt;string, Empty&gt; name);
	Rev_Tip_Nd(Rev_Tree* tr, Rev_Tip_NC* node_contnr, int num_sites, boost::variant&lt;string, Empty&gt; name);
public:
	static Rev_Tip_Nd* create(Rev_Tree* tr, Rev_Tip_NC* node_contnr, string nucl_seq, boost::variant&lt;string, Empty&gt; name = Empty());
	static Rev_Tip_Nd* create(Rev_Tree* tr, Rev_Tip_NC* node_contnr, int num_sites, boost::variant&lt;string, Empty&gt; name = Empty());
};
</code></pre>
<p>mit den Factory-Methoden</p>
<pre><code class="language-cpp">Rev_Tip_Nd* Rev_Tip_Nd::create(Rev_Tree* tr, Rev_Tip_NC* node_contnr, string nucl_seq, boost::variant&lt;string, Empty&gt; name)
{
	Rev_Tip_Nd* n = new Rev_Tip_Nd(tr, node_contnr, nucl_seq, name);
	n-&gt;alloc_log_subst_prob();   // Methode von Prob_Nd, kann erst aufgerufen werden, wenn ein Konstruktor von Rev_Tip_Nd aufgerufen worden ist
	...
	return n;
}

Rev_Tip_Nd* Rev_Tip_Nd::create(Rev_Tree* tr, Rev_Tip_NC* node_contnr, int num_sites, boost::variant&lt;string, Empty&gt; name)
{
	Rev_Tip_Nd* n = new Rev_Tip_Nd(tr, node_contnr, num_sites, name);
	n-&gt;alloc_log_subst_prob();   // s.o.
	...
	return n;
}
</code></pre>
<p>Da alloc_log_subst_prob() immer nach dem Konstruktor-Aufruf von Rev_Tip_Nd aufgerufen werden muss, frage ich mich, ob man das auch irgendwie so programmieren kann, dass man nicht vergessen kann, alloc_log_subst_prob() in einer Factory-Methode aufzurufen.</p>
<p>Hierbei ist noch wichtig, dass es auch noch zwei andere aus Prob_Nd abgeleitete Klassen Rev_Coal_Nd und Rev_Rec_Nd gibt, wobei die Konstruktoren bzw. Factory-Methoden von Rev_Coal_Nd und Rev_Rec_Nd andere Signaturen als Rev_Tip_Nd haben, z.B.</p>
<pre><code class="language-cpp">Rev_Coal_Nd* Rev_Coal_Nd::create(Rev_Tree* tr, Rev_Coal_NC* node_contnr, Rev_Nd* first_old_node, Rev_Nd* second_old_node, boost::variant&lt;string, Empty&gt; name)
{
	Rev_Coal_Nd* n = new Rev_Coal_Nd(tr, node_contnr, first_old_node, second_old_node, name);
	n-&gt;alloc_log_subst_prob();
	...
	return n;
}
</code></pre>
<p>Ich dachte dabei insbesondere an CRTP, mir ist aber unklar wie das angesichts verschiedener Signaturen der Factory-Methoden realisiert werden kann.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/243089/crtp-bei-factory-methoden-mit-verschiedener-signatur</link><generator>RSS for Node</generator><lastBuildDate>Sun, 20 Sep 2026 14:56:46 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/243089.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 12 Jun 2009 07:58:34 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to CRTP bei Factory-Methoden mit verschiedener Signatur on Fri, 12 Jun 2009 07:58:34 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich habe zwei Klassen (hier nur Auszuege gezeigt)</p>
<pre><code class="language-cpp">class Prob_Nd 
{
protected:
	Prob_Nd();
	void alloc_log_subst_prob();
};
</code></pre>
<p>und</p>
<pre><code class="language-cpp">class Rev_Tip_Nd : public Prob_Nd
{
private:
	Rev_Tip_Nd(Rev_Tree* tr, Rev_Tip_NC* node_contnr, string nucl_seq, boost::variant&lt;string, Empty&gt; name);
	Rev_Tip_Nd(Rev_Tree* tr, Rev_Tip_NC* node_contnr, int num_sites, boost::variant&lt;string, Empty&gt; name);
public:
	static Rev_Tip_Nd* create(Rev_Tree* tr, Rev_Tip_NC* node_contnr, string nucl_seq, boost::variant&lt;string, Empty&gt; name = Empty());
	static Rev_Tip_Nd* create(Rev_Tree* tr, Rev_Tip_NC* node_contnr, int num_sites, boost::variant&lt;string, Empty&gt; name = Empty());
};
</code></pre>
<p>mit den Factory-Methoden</p>
<pre><code class="language-cpp">Rev_Tip_Nd* Rev_Tip_Nd::create(Rev_Tree* tr, Rev_Tip_NC* node_contnr, string nucl_seq, boost::variant&lt;string, Empty&gt; name)
{
	Rev_Tip_Nd* n = new Rev_Tip_Nd(tr, node_contnr, nucl_seq, name);
	n-&gt;alloc_log_subst_prob();   // Methode von Prob_Nd, kann erst aufgerufen werden, wenn ein Konstruktor von Rev_Tip_Nd aufgerufen worden ist
	...
	return n;
}

Rev_Tip_Nd* Rev_Tip_Nd::create(Rev_Tree* tr, Rev_Tip_NC* node_contnr, int num_sites, boost::variant&lt;string, Empty&gt; name)
{
	Rev_Tip_Nd* n = new Rev_Tip_Nd(tr, node_contnr, num_sites, name);
	n-&gt;alloc_log_subst_prob();   // s.o.
	...
	return n;
}
</code></pre>
<p>Da alloc_log_subst_prob() immer nach dem Konstruktor-Aufruf von Rev_Tip_Nd aufgerufen werden muss, frage ich mich, ob man das auch irgendwie so programmieren kann, dass man nicht vergessen kann, alloc_log_subst_prob() in einer Factory-Methode aufzurufen.</p>
<p>Hierbei ist noch wichtig, dass es auch noch zwei andere aus Prob_Nd abgeleitete Klassen Rev_Coal_Nd und Rev_Rec_Nd gibt, wobei die Konstruktoren bzw. Factory-Methoden von Rev_Coal_Nd und Rev_Rec_Nd andere Signaturen als Rev_Tip_Nd haben, z.B.</p>
<pre><code class="language-cpp">Rev_Coal_Nd* Rev_Coal_Nd::create(Rev_Tree* tr, Rev_Coal_NC* node_contnr, Rev_Nd* first_old_node, Rev_Nd* second_old_node, boost::variant&lt;string, Empty&gt; name)
{
	Rev_Coal_Nd* n = new Rev_Coal_Nd(tr, node_contnr, first_old_node, second_old_node, name);
	n-&gt;alloc_log_subst_prob();
	...
	return n;
}
</code></pre>
<p>Ich dachte dabei insbesondere an CRTP, mir ist aber unklar wie das angesichts verschiedener Signaturen der Factory-Methoden realisiert werden kann.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1725411</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1725411</guid><dc:creator><![CDATA[ingobulla]]></dc:creator><pubDate>Fri, 12 Jun 2009 07:58:34 GMT</pubDate></item><item><title><![CDATA[Reply to CRTP bei Factory-Methoden mit verschiedener Signatur on Fri, 12 Jun 2009 08:39:46 GMT]]></title><description><![CDATA[<p>Drei Fragen:<br />
1. Muss wirklich der Konstruktor von <code>Rev_Tip_Nd</code> vollständig durch sein? Kann man die Methode nicht im Rumpf des <code>Prod_Nd</code> Konstruktors aufrufen?<br />
2. Wie stark unterscheiden sich die Funktionssignaturen im Sinne von Anzahl Argumenten und Defaultargumenten?<br />
3. Der Aufruf der Funktion am Ende des Konstruktorrumpfes von <code>Rev_Tip_Nd</code> würde nichts bringen, oder?</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1725440</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1725440</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Fri, 12 Jun 2009 08:39:46 GMT</pubDate></item><item><title><![CDATA[Reply to CRTP bei Factory-Methoden mit verschiedener Signatur on Fri, 12 Jun 2009 09:15:04 GMT]]></title><description><![CDATA[<p>Dravere schrieb:</p>
<blockquote>
<p><code>Prod_Nd</code></p>
</blockquote>
<p>Das bestärkt meinen ersten Eindruck: ich finde die Nomenklatur überaus kontraproduktiv.</p>
<p>Was das Problem anbelangt, so wäre anzumerken, daß Methoden, deren Aufruf nur in bestimmten Zuständen des Objektes gültig sind, vermieden werden sollten. Alle derartigen Aktionen sollten in diesem Falle im Konstruktor stattfinden.</p>
<p>Eine Möglichkeit wäre, die notwendige Initialisierungsabfolge durch eine veränderte Klassenstruktur auszudrücken:</p>
<pre><code class="language-cpp">class A
{
protected:
    struct InnerObject {};

private:
    InnerObject* innerObj;

protected:
    InnerObject* getInnerObj (void) { return innerObj; }
    A (InnerObject* _innerObj)
     : innerObj (_innerObj)
    { /* initialize innerObj */ }
};

class B : public A
{
protected:
    struct InnerObject : A::InnerObject
    {
        InnerObject (int) {}
    };

public:
    B (int i)
     : A (new InnerObject (i))
    {}
};
</code></pre>
<p>Wenn dann das Ganze noch typsicher sein soll (d.h., wenn du in B ohne Cast an <code>static_cast &lt;B::InnerObject*&gt; (getInnerObj ())</code> kommen können willst), kannst du das hier probieren:</p>
<pre><code class="language-cpp">struct InnerCBase {};
template &lt;typename T&gt;
  struct InnerC;

template &lt;class B&gt;
    class C
{
protected:
    struct InnerObject {};
private:
    InnerC &lt;B&gt;* innerObj;
protected:
    InnerC &lt;B&gt;* getInnerObj (void) { return innerObj; }
    C (InnerC &lt;B&gt;* _innerObj)
     : innerObj (_innerObj)
    { /*initialize innerObj */ }
};

class D : public C &lt;D&gt;
{
public:
    D (int i);
};

template &lt;&gt;
    struct InnerC &lt;D&gt;
{
    InnerC (int) {}
};

D:: D (int i)
 : C &lt;D&gt; (new InnerC &lt;D&gt; (i))
{
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1725460</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1725460</guid><dc:creator><![CDATA[audacia]]></dc:creator><pubDate>Fri, 12 Jun 2009 09:15:04 GMT</pubDate></item></channel></rss>