<?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[Ausnahmesichere kovariante Rückgabetypen]]></title><description><![CDATA[<p>In meinem aktuellen Programm komme ich nicht darum herum, das Clone-Pattern zu implementieren.</p>
<p>Von <a href="http://www.lwithers.me.uk/articles/covariant.html" rel="nofollow">da</a> habe ich den folgenden Code:</p>
<pre><code class="language-cpp">struct Base {
    virtual Base* clone() const { return new Base(this); }
};

struct Derived : Base {
    virtual Base* clone() const { return new Derived(this); }
};
</code></pre>
<p>Rohe Zeiger zurückgeben ist heutzutage allerdings out.</p>
<p>Schöner wäre so etwas:</p>
<pre><code class="language-cpp">struct Base {
    virtual unique_ptr&lt;Base&gt; clone() const { return make_unique&lt;Base&gt;(this); }
};

struct Derived : Base {
    // invalid covariant return type for ‘virtual std::unique_ptr&lt;Derived&gt; Derived::clone() const’
    virtual unique_ptr&lt;Derived&gt; clone() const { return make_unique&lt;Derived&gt;(this); }
};
</code></pre>
<p>Ich will quasi die erste Variante einfach mit <code>unique_ptr</code> s. Auf die Kovarianz bin ich angewiesen. Gibt es da einen eleganten Weg?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/310485/ausnahmesichere-kovariante-rückgabetypen</link><generator>RSS for Node</generator><lastBuildDate>Tue, 04 Aug 2026 17:34:39 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/310485.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 12 Nov 2012 19:49:28 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Ausnahmesichere kovariante Rückgabetypen on Mon, 12 Nov 2012 19:49:28 GMT]]></title><description><![CDATA[<p>In meinem aktuellen Programm komme ich nicht darum herum, das Clone-Pattern zu implementieren.</p>
<p>Von <a href="http://www.lwithers.me.uk/articles/covariant.html" rel="nofollow">da</a> habe ich den folgenden Code:</p>
<pre><code class="language-cpp">struct Base {
    virtual Base* clone() const { return new Base(this); }
};

struct Derived : Base {
    virtual Base* clone() const { return new Derived(this); }
};
</code></pre>
<p>Rohe Zeiger zurückgeben ist heutzutage allerdings out.</p>
<p>Schöner wäre so etwas:</p>
<pre><code class="language-cpp">struct Base {
    virtual unique_ptr&lt;Base&gt; clone() const { return make_unique&lt;Base&gt;(this); }
};

struct Derived : Base {
    // invalid covariant return type for ‘virtual std::unique_ptr&lt;Derived&gt; Derived::clone() const’
    virtual unique_ptr&lt;Derived&gt; clone() const { return make_unique&lt;Derived&gt;(this); }
};
</code></pre>
<p>Ich will quasi die erste Variante einfach mit <code>unique_ptr</code> s. Auf die Kovarianz bin ich angewiesen. Gibt es da einen eleganten Weg?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2270245</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2270245</guid><dc:creator><![CDATA[corian]]></dc:creator><pubDate>Mon, 12 Nov 2012 19:49:28 GMT</pubDate></item><item><title><![CDATA[Reply to Ausnahmesichere kovariante Rückgabetypen on Mon, 12 Nov 2012 19:52:32 GMT]]></title><description><![CDATA[<p>Zu weit oben kopiert, das erste Snippet sollte lauten</p>
<pre><code class="language-cpp">struct Base {
    virtual Base* clone() const { return new Base(this); }
};

struct Derived : Base {
    virtual Derived* clone() const { return new Derived(this); }
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2270247</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2270247</guid><dc:creator><![CDATA[corian]]></dc:creator><pubDate>Mon, 12 Nov 2012 19:52:32 GMT</pubDate></item><item><title><![CDATA[Reply to Ausnahmesichere kovariante Rückgabetypen on Mon, 12 Nov 2012 20:34:00 GMT]]></title><description><![CDATA[<p>Hmmm, im Standard ist ganz klar definiert wie <em>covariant return type</em> funktioniert und das geht nur direkt mit Basisklassenzeigern bzw. deren Ableitungen.</p>
<p>Was dir aber als gute Möglichkeit bleibt, ist ein privates virtual Base*/Derived* cloneX() zu schreiben und ein public unique_ptr&lt;Base/Derived&gt; cloneY() diese aufrufen zu lassen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2270264</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2270264</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Mon, 12 Nov 2012 20:34:00 GMT</pubDate></item><item><title><![CDATA[Reply to Ausnahmesichere kovariante Rückgabetypen on Mon, 12 Nov 2012 20:41:15 GMT]]></title><description><![CDATA[<p>Ja, direkt std::unique_ptr zurückgeben wirds nicht spielen. Ich würde wohl was in der Richtung versuchen:</p>
<pre><code class="language-cpp">template &lt;class T&gt;
auto clone(T* obj) -&gt; std::unique_ptr&lt;typename std::remove_pointer&lt;decltype(obj-&gt;clone())&gt;::type&gt;
{
  return std::unique_ptr&lt;typename std::remove_pointer&lt;decltype(obj-&gt;clone())&gt;::type&gt;(obj-&gt;clone());
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2270268</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2270268</guid><dc:creator><![CDATA[dot]]></dc:creator><pubDate>Mon, 12 Nov 2012 20:41:15 GMT</pubDate></item><item><title><![CDATA[Reply to Ausnahmesichere kovariante Rückgabetypen on Mon, 12 Nov 2012 20:51:24 GMT]]></title><description><![CDATA[<p>dot schrieb:</p>
<blockquote>
<p>Ja, direkt std::unique_ptr zurückgeben wirds nicht spielen. Ich würde wohl was in der Richtung versuchen:</p>
<pre><code class="language-cpp">template &lt;class T&gt;
auto clone(T* obj) -&gt; std::unique_ptr&lt;typename std::remove_pointer&lt;decltype(obj-&gt;clone())&gt;::type&gt;
{
  return std::unique_ptr&lt;typename std::remove_pointer&lt;decltype(obj-&gt;clone())&gt;::type&gt;(obj-&gt;clone());
}
</code></pre>
</blockquote>
<p>decltype nimmt nur den statischen Typ, insofern ist decltype(obj-&gt;clone()) immer decltype(T*).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2270271</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2270271</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Mon, 12 Nov 2012 20:51:24 GMT</pubDate></item><item><title><![CDATA[Reply to Ausnahmesichere kovariante Rückgabetypen on Mon, 12 Nov 2012 20:53:20 GMT]]></title><description><![CDATA[<p>lol, das ist natürlich richtig, frag nicht, was ich mir dabei gedacht hab...</p>
<pre><code class="language-cpp">template &lt;class T&gt; 
std::unique_ptr&lt;T&gt; clone(T* obj)
{ 
  return std::unique_ptr&lt;T&gt;(obj-&gt;clone()); 
}
</code></pre>
<p>ist natürlich viel lesbarer...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2270272</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2270272</guid><dc:creator><![CDATA[dot]]></dc:creator><pubDate>Mon, 12 Nov 2012 20:53:20 GMT</pubDate></item><item><title><![CDATA[Reply to Ausnahmesichere kovariante Rückgabetypen on Mon, 12 Nov 2012 20:56:26 GMT]]></title><description><![CDATA[<p>Super dot, so was ähnliches hatte ich auch. Privat und virtuell mit Pointern, öffentlich die statische Funktion clone:</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
std::unique_ptr&lt;T&gt; clone(T const&amp; obj)
{
  return std::unique_ptr&lt;T&gt;(obj.clone());
}
</code></pre>
<p>Geht scheinbar nicht als Memberfunktion, danke vielmals.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2270273</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2270273</guid><dc:creator><![CDATA[corian]]></dc:creator><pubDate>Mon, 12 Nov 2012 20:56:26 GMT</pubDate></item><item><title><![CDATA[Reply to Ausnahmesichere kovariante Rückgabetypen on Mon, 12 Nov 2012 20:59:57 GMT]]></title><description><![CDATA[<p>Wobei ich meinen letzten Post wieder zurücknehmen muss, ich hab mir natürlich was dabei gedacht. clone() hat nicht notwendigerweise immer einen covariant return type und die Variante mit decltype() funktioniert eben auch, wenn dem nicht so ist...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2270274</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2270274</guid><dc:creator><![CDATA[dot]]></dc:creator><pubDate>Mon, 12 Nov 2012 20:59:57 GMT</pubDate></item><item><title><![CDATA[Reply to Ausnahmesichere kovariante Rückgabetypen on Mon, 12 Nov 2012 21:02:11 GMT]]></title><description><![CDATA[<p>? Ich habe doch eine saubere Möglichkeit genannt:</p>
<pre><code>struct Base { 
    unique_ptr&lt;Base&gt; clone() const { return cloneMe(); } 
private:
    virtual Base* cloneMe() const { return new Base(*this); }
}; 

struct Derived : Base { 
    unique_ptr&lt;Derived&gt; clone() const { return cloneMe(); } 
private:
    virtual Derived* cloneMe() const { return new Derived(*this); }
};
</code></pre>
<p>So muss du deinen bestehenden Client-Code auch nicht anpassen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2270276</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2270276</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Mon, 12 Nov 2012 21:02:11 GMT</pubDate></item><item><title><![CDATA[Reply to Ausnahmesichere kovariante Rückgabetypen on Mon, 12 Nov 2012 21:04:50 GMT]]></title><description><![CDATA[<p>KasF schrieb:</p>
<blockquote>
<p>? Ich habe doch eine saubere Möglichkeit genannt</p>
</blockquote>
<p>Dann hab ich das falsch verstanden. Ich dachte clone würde bei jeder Klasse anders heissen.<br />
An das hab ich gar nicht gedacht, top <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f44d.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--thumbs_up"
      title=":+1:"
      alt="👍"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2270277</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2270277</guid><dc:creator><![CDATA[corian]]></dc:creator><pubDate>Mon, 12 Nov 2012 21:04:50 GMT</pubDate></item><item><title><![CDATA[Reply to Ausnahmesichere kovariante Rückgabetypen on Mon, 12 Nov 2012 21:13:01 GMT]]></title><description><![CDATA[<p>Ist natürlich auch eine Lösung, hat halt den Nachteil, dass man in jeder Klasse, die ein kovariates clone() unterstützten soll die entsprechende Methode extra definieren muss. Der Vorteil ist wiederum, dass es keinen Weg gibt, ein Objekt nicht über std::unique_ptr zu klonen, beim anderen Ansatz müsste man dafür über friend arbeiten...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2270280</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2270280</guid><dc:creator><![CDATA[dot]]></dc:creator><pubDate>Mon, 12 Nov 2012 21:13:01 GMT</pubDate></item><item><title><![CDATA[Reply to Ausnahmesichere kovariante Rückgabetypen on Mon, 12 Nov 2012 21:17:33 GMT]]></title><description><![CDATA[<p>dot schrieb:</p>
<blockquote>
<p>Ist natürlich auch eine Lösung, hat halt den Nachteil, dass man in jeder Klasse, die ein kovariates clone() unterstützten soll die entsprechende Methode extra definieren muss.</p>
</blockquote>
<p>Ach, ein STRG+R tuts auch <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="😉"
    /> Es ist halt eine Änderung im Code gewünscht und die erfordert eben Arbeit, da kommt man nicht drumherum. Hauptsache der Client erleidet daraus keinen Nachteil.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2270281</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2270281</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Mon, 12 Nov 2012 21:17:33 GMT</pubDate></item><item><title><![CDATA[Reply to Ausnahmesichere kovariante Rückgabetypen on Mon, 12 Nov 2012 21:30:31 GMT]]></title><description><![CDATA[<p>Ist ja angeblich eh guter Stil. <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="😉"
    /><br />
<a href="http://www.gotw.ca/publications/mill18.htm" rel="nofollow">http://www.gotw.ca/publications/mill18.htm</a></p>
<p>Herb Sutter schrieb:</p>
<blockquote>
<p>Guideline #2: Prefer to make virtual functions private.</p>
</blockquote>
]]></description><link>https://www.c-plusplus.net/forum/post/2270285</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2270285</guid><dc:creator><![CDATA[cooky451]]></dc:creator><pubDate>Mon, 12 Nov 2012 21:30:31 GMT</pubDate></item><item><title><![CDATA[Reply to Ausnahmesichere kovariante Rückgabetypen on Mon, 12 Nov 2012 22:07:51 GMT]]></title><description><![CDATA[<p>KasF schrieb:</p>
<blockquote>
<pre><code>unique_ptr&lt;Base&gt; clone() const { return cloneMe(); } 
unique_ptr&lt;Derived&gt; clone() const { return cloneMe(); }
</code></pre>
</blockquote>
<p>Da scheine ich ja was vergessen zu haben <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="🙂"
    /> Einfach return unique_ptr&lt;T&gt;(cloneMe()) daraus machen. Btw, corian welchen Compiler benutzt, dass du schon make_unique hast?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2270292</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2270292</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Mon, 12 Nov 2012 22:07:51 GMT</pubDate></item><item><title><![CDATA[Reply to Ausnahmesichere kovariante Rückgabetypen on Mon, 12 Nov 2012 22:32:57 GMT]]></title><description><![CDATA[<p>KasF schrieb:</p>
<blockquote>
<p>Da scheine ich ja was vergessen zu haben <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="🙂"
    /> Einfach return unique_ptr&lt;T&gt;(cloneMe()) daraus machen. Btw, corian welchen Compiler benutzt, dass du schon make_unique hast?</p>
</blockquote>
<p>Das make_unique hab ich mir selber geschrieben.<br />
Ein <code>return {cloneMe()};</code> reicht auch übrigens schon.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2270297</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2270297</guid><dc:creator><![CDATA[corian]]></dc:creator><pubDate>Mon, 12 Nov 2012 22:32:57 GMT</pubDate></item><item><title><![CDATA[Reply to Ausnahmesichere kovariante Rückgabetypen on Mon, 12 Nov 2012 22:43:18 GMT]]></title><description><![CDATA[<p>corian schrieb:</p>
<blockquote>
<p>Ein <code>return {cloneMe()};</code> reicht auch übrigens schon.</p>
</blockquote>
<p>unique_ptr's Konstruktor ist explicit, zumindest sollte es das bei dir sein und folgedessen obiger Code nicht funktionieren. Wenn das oben bei dir wirklich funktioniert, dann blitzt und donnert es aber gewaltig mit der RAII-Philosophie.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2270299</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2270299</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Mon, 12 Nov 2012 22:43:18 GMT</pubDate></item><item><title><![CDATA[Reply to Ausnahmesichere kovariante Rückgabetypen on Tue, 13 Nov 2012 10:55:53 GMT]]></title><description><![CDATA[<p>KasF schrieb:</p>
<blockquote>
<p>corian schrieb:</p>
<blockquote>
<p>Ein <code>return {cloneMe()};</code> reicht auch übrigens schon.</p>
</blockquote>
<p>unique_ptr's Konstruktor ist explicit, zumindest sollte es das bei dir sein und folgedessen obiger Code nicht funktionieren. Wenn das oben bei dir wirklich funktioniert, dann blitzt und donnert es aber gewaltig mit der RAII-Philosophie.</p>
</blockquote>
<p>Ich war mir vorhin nicht sicher, ob diese Syntax wirklich nicht mit explicit Konstruktoren nutzbar ist und habe das nachgeguckt. Ein &quot;return {...};&quot; ist eine copy-list-initialization. Mit dieser kann man keine explicit Konstruktoren aufrufen. Du hast also Recht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2270414</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2270414</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Tue, 13 Nov 2012 10:55:53 GMT</pubDate></item></channel></rss>