<?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[Baum mit unique_ptr?]]></title><description><![CDATA[<p>Hallo,</p>
<p>angenommen ich habe einen einfachen Interpreter wie hier (kann Ausdrücke addieren):</p>
<pre><code>#include &lt;iostream&gt;

struct Node
{
	virtual int eval() = 0;
};

struct NodeValue : Node
{
	int value;
	NodeValue(int value) : value(value) {}
	virtual int eval() { return value; }
};

struct NodeAdd : Node
{
	Node *left, *right;
	NodeAdd(Node *left, Node *right) : left(left), right(right) {}
	virtual int eval() { return left-&gt;eval() + right-&gt;eval(); }
};

int main()
{
	Node *node = new NodeAdd(new NodeValue(2), new NodeValue(5));
	std::cout &lt;&lt; node-&gt;eval() &lt;&lt; &quot;\n&quot;; // 2 + 5 = 7
}
</code></pre>
<p>Das funktioniert soweit (ist mehr oder weniger das selbe wie aus dem <a href="https://www.c-plusplus.net/forum/268247">Interpreterbau</a> Tutorial).</p>
<p>Problem ist natürlich dass das so ein Memory Leak ist, da der Speicher nicht wieder freigegeben wird.<br />
Deswegen würde ich das gerne auf unique_ptr umstellen um das automatisiert aufgeräumt zu bekommen. Mein Versuch:</p>
<pre><code>#include &lt;iostream&gt;
#include &lt;memory&gt;
using namespace std;

struct Node
{
	virtual int eval() = 0;
};

struct NodeValue : Node
{
	int value;
	NodeValue(int value) : value(value) {}
	virtual int eval() { return value; }
};

struct NodeAdd : Node
{
	unique_ptr&lt;Node&gt; left, right;
	NodeAdd(unique_ptr&lt;Node&gt; left, unique_ptr&lt;Node&gt; right) : left(move(left)), right(move(right)) {}
	virtual int eval() { return left-&gt;eval() + right-&gt;eval(); }
};

int main()
{
	auto node = unique_ptr&lt;Node&gt;(new NodeAdd(unique_ptr&lt;Node&gt;(new NodeValue(2)), unique_ptr&lt;Node&gt;(new NodeValue(5))));
	std::cout &lt;&lt; node-&gt;eval() &lt;&lt; &quot;\n&quot;; 
}
</code></pre>
<p>Das funktioniert auch, allerdings habe ich ein paar Fragen/Zweifel:</p>
<ul>
<li>Wird hier sämtlicher Speicher korrekt wieder aufgeräumt?</li>
<li>Wieso kann ich den <code>unique_ptr</code> überhaupt per Value an den Konstruktor von <code>NodeAdd</code> übergeben? Das <code>move</code> findet ja erst in der Initializer-List &quot;statt&quot;, um überhaupt dahin zu kommen müsste doch erstmal eine Kopie des Pointers erstellt werden?</li>
<li>Wenn ich <code>node</code> an eine Funktion übergeben will, muss ich selbigen moven. Soweit so gut, aber ich würde jetzt gerne einen Functor um <code>node</code> wrappen, sodass ich diesen wie eine normale Funktion benutzen kann. Dazu würde ich den auch gerne einfach zwischen Funktionen hin und hergeben können ohne mir um <code>move</code> Gedanken machen zu müssen (wie einen <code>std::vector</code> z.B.). Wie macht man das am geschicktesten?</li>
</ul>
]]></description><link>https://www.c-plusplus.net/forum/topic/337418/baum-mit-unique_ptr</link><generator>RSS for Node</generator><lastBuildDate>Fri, 17 Apr 2026 23:25:50 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/337418.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 31 Mar 2016 18:56:37 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Baum mit unique_ptr? on Thu, 31 Mar 2016 18:56:37 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>angenommen ich habe einen einfachen Interpreter wie hier (kann Ausdrücke addieren):</p>
<pre><code>#include &lt;iostream&gt;

struct Node
{
	virtual int eval() = 0;
};

struct NodeValue : Node
{
	int value;
	NodeValue(int value) : value(value) {}
	virtual int eval() { return value; }
};

struct NodeAdd : Node
{
	Node *left, *right;
	NodeAdd(Node *left, Node *right) : left(left), right(right) {}
	virtual int eval() { return left-&gt;eval() + right-&gt;eval(); }
};

int main()
{
	Node *node = new NodeAdd(new NodeValue(2), new NodeValue(5));
	std::cout &lt;&lt; node-&gt;eval() &lt;&lt; &quot;\n&quot;; // 2 + 5 = 7
}
</code></pre>
<p>Das funktioniert soweit (ist mehr oder weniger das selbe wie aus dem <a href="https://www.c-plusplus.net/forum/268247">Interpreterbau</a> Tutorial).</p>
<p>Problem ist natürlich dass das so ein Memory Leak ist, da der Speicher nicht wieder freigegeben wird.<br />
Deswegen würde ich das gerne auf unique_ptr umstellen um das automatisiert aufgeräumt zu bekommen. Mein Versuch:</p>
<pre><code>#include &lt;iostream&gt;
#include &lt;memory&gt;
using namespace std;

struct Node
{
	virtual int eval() = 0;
};

struct NodeValue : Node
{
	int value;
	NodeValue(int value) : value(value) {}
	virtual int eval() { return value; }
};

struct NodeAdd : Node
{
	unique_ptr&lt;Node&gt; left, right;
	NodeAdd(unique_ptr&lt;Node&gt; left, unique_ptr&lt;Node&gt; right) : left(move(left)), right(move(right)) {}
	virtual int eval() { return left-&gt;eval() + right-&gt;eval(); }
};

int main()
{
	auto node = unique_ptr&lt;Node&gt;(new NodeAdd(unique_ptr&lt;Node&gt;(new NodeValue(2)), unique_ptr&lt;Node&gt;(new NodeValue(5))));
	std::cout &lt;&lt; node-&gt;eval() &lt;&lt; &quot;\n&quot;; 
}
</code></pre>
<p>Das funktioniert auch, allerdings habe ich ein paar Fragen/Zweifel:</p>
<ul>
<li>Wird hier sämtlicher Speicher korrekt wieder aufgeräumt?</li>
<li>Wieso kann ich den <code>unique_ptr</code> überhaupt per Value an den Konstruktor von <code>NodeAdd</code> übergeben? Das <code>move</code> findet ja erst in der Initializer-List &quot;statt&quot;, um überhaupt dahin zu kommen müsste doch erstmal eine Kopie des Pointers erstellt werden?</li>
<li>Wenn ich <code>node</code> an eine Funktion übergeben will, muss ich selbigen moven. Soweit so gut, aber ich würde jetzt gerne einen Functor um <code>node</code> wrappen, sodass ich diesen wie eine normale Funktion benutzen kann. Dazu würde ich den auch gerne einfach zwischen Funktionen hin und hergeben können ohne mir um <code>move</code> Gedanken machen zu müssen (wie einen <code>std::vector</code> z.B.). Wie macht man das am geschicktesten?</li>
</ul>
]]></description><link>https://www.c-plusplus.net/forum/post/2491969</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2491969</guid><dc:creator><![CDATA[happystudent]]></dc:creator><pubDate>Thu, 31 Mar 2016 18:56:37 GMT</pubDate></item><item><title><![CDATA[Reply to Baum mit unique_ptr? on Fri, 01 Apr 2016 05:37:29 GMT]]></title><description><![CDATA[<p>1. Ja. Solange du nicht release aufrufst und den Rückgabezeiger fallen lässt, ist alles sicher.<br />
2. In zeile 26 erstellst du ein temporäres unique_ptr-Objekt, welches eine rvalue-Referenz ausbildet, wie das bei allen temporären Objekten der Fall ist. Diese wird an den Movekonstruktor vom unique_ptr-Argument gegeben.<br />
3. Wenn du Objekte an Funktionen übergibst, reicht eine übliche const-Referenz auf das Objekt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2491999</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2491999</guid><dc:creator><![CDATA[Techel]]></dc:creator><pubDate>Fri, 01 Apr 2016 05:37:29 GMT</pubDate></item><item><title><![CDATA[Reply to Baum mit unique_ptr? on Fri, 01 Apr 2016 07:38:45 GMT]]></title><description><![CDATA[<p>happystudent schrieb:</p>
<blockquote>
<ul>
<li>Wird hier sämtlicher Speicher korrekt wieder aufgeräumt?</li>
</ul>
</blockquote>
<p>Nicht, wenn eine Exception auftritt. Ein Compiler darf den Ausdruck zum Beispiel in dieser Reihenfolge auswerten:</p>
<pre><code class="language-cpp">unique_ptr&lt;Node&gt;(new NodeAdd(unique_ptr&lt;Node&gt;(new NodeValue(2)), unique_ptr&lt;Node&gt;(new NodeValue(5))))
                                              1111111111111111
											                     2222222222222222222222222222222222
							 3333333333333333333333333333333333
</code></pre>
<p>Wenn das zweite <code>new</code> wirft, wird das Ergebnis des ersten nie freigegeben, weil der <code>unique_ptr</code> noch nicht konstruiert worden ist.<br />
Um dieses Problem zu vermeiden, benutzt man <code>make_unique</code> :</p>
<pre><code class="language-cpp">std::make_unique&lt;NodeAdd&gt;(std::make_unique&lt;NodeValue&gt;(2), std::make_unique&lt;NodeValue&gt;(5))
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2492008</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2492008</guid><dc:creator><![CDATA[TyRoXx]]></dc:creator><pubDate>Fri, 01 Apr 2016 07:38:45 GMT</pubDate></item><item><title><![CDATA[Reply to Baum mit unique_ptr? on Fri, 01 Apr 2016 08:08:35 GMT]]></title><description><![CDATA[<p>happystudent schrieb:</p>
<blockquote>
<p>Wenn ich <code>node</code> an eine Funktion übergeben will, muss ich selbigen moven. Soweit so gut, aber ich würde jetzt gerne einen Functor um <code>node</code> wrappen, sodass ich diesen wie eine normale Funktion benutzen kann. Dazu würde ich den auch gerne einfach zwischen Funktionen hin und hergeben können ohne mir um <code>move</code> Gedanken machen zu müssen (wie einen <code>std::vector</code> z.B.). Wie macht man das am geschicktesten?</p>
</blockquote>
<p>unique_ptr liefert mit get einen ganz normalen Pointer. Wenn du nicht den Besitzt weitergeben willst, solltest du das verwenden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2492010</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2492010</guid><dc:creator><![CDATA[manni66]]></dc:creator><pubDate>Fri, 01 Apr 2016 08:08:35 GMT</pubDate></item><item><title><![CDATA[Reply to Baum mit unique_ptr? on Fri, 01 Apr 2016 19:05:55 GMT]]></title><description><![CDATA[<p>Der Destruktor ist nicht virtuell.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2492058</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2492058</guid><dc:creator><![CDATA[Mechanics]]></dc:creator><pubDate>Fri, 01 Apr 2016 19:05:55 GMT</pubDate></item><item><title><![CDATA[Reply to Baum mit unique_ptr? on Sat, 02 Apr 2016 07:38:54 GMT]]></title><description><![CDATA[<p>Kleine Randfrage zu den Exceptions bei new</p>
<p>TyRoXx schrieb:</p>
<blockquote>
<p>happystudent schrieb:</p>
<blockquote>
<ul>
<li>Wird hier sämtlicher Speicher korrekt wieder aufgeräumt?</li>
</ul>
</blockquote>
<p>Nicht, wenn eine Exception auftritt.[...]</p>
</blockquote>
<p>Wenn bei new eine Exception auftritt, dann ist doch eh schon alles zu spät oder? In welchem Anwendungsfall interessiert mich das den?</p>
<p>Angenommen ich hab ein Programm, bei einer Allokation wird eine Exception geworfen. Meine Annahme ist die Exception wird nur geworfen da mein Rechner aktuell total am Anschlag ist und kein weiterer Speicher mehr zur Verfügung steht. Somit ist auch ein sinnvoller Programmablauf (aus meiner Sicht) nicht mehr möglich, da jede weitere Allokation auch nicht mehr möglich ist. Und somit bleibt doch nur noch der Programmcrash und das Betriebssystem räumt anschließend den Speicher auf.</p>
<p>Drei Rückfragen:<br />
(1) Behandelt ihr die mögliche Exceptions die bei &quot;new&quot; auftreten könnten?<br />
(2) Aus welchem Grund macht ihr das?<br />
(3) Gibt es dann noch einen sinnvollen Programmablauf?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2492087</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2492087</guid><dc:creator><![CDATA[__jb__]]></dc:creator><pubDate>Sat, 02 Apr 2016 07:38:54 GMT</pubDate></item><item><title><![CDATA[Reply to Baum mit unique_ptr? on Sat, 02 Apr 2016 08:24:28 GMT]]></title><description><![CDATA[<p>1 Ja<br />
2 s.u.<br />
3 Vermutlich nicht</p>
<p>2...<br />
Es macht einfach keinen Sinn sich an jeder 2. Stelle zu überlegen &quot;kann ich hier rumsauen&quot;? Weil es mühsam ist. Wenn ich gleich überall sauber programmiere spare ich mir die Überlegung.<br />
Und weil man viel zu schnell in Richtung &quot;zu oft rumsauen&quot; driftet. Und dann an Stellen rumsaut wo es doch nicht OK gewesen wäre. Weil halt was übersehen hat und der Fall den man für &quot;kann eh nicht sein&quot; gehalten hat doch vorkommen kann. Oder sich vielleicht auch irgendwo die Regeln geändert haben.<br />
Und weil es mMn. dämlich ist mal-so, mal-so zu programmieren. Wozu sollte ich die &quot;Fähigkeit&quot; unsauber zu programmieren trainieren? Was bringt mir die?</p>
<p>Weitere Argument dafür Exceptions &quot;bei new&quot; zu behandeln:</p>
<ul>
<li><code>bad_alloc</code> ist nicht das einzige was bei <code>new T()</code> fliegen kann. Wenn <code>T</code> ne Klasse ist, dann kann der Konstruktor beliebige Exceptions aus beliebigen Gründen werfen. Und so Sachen wie &quot;File not Found&quot; sind jetzt weder selten noch &quot;unbehandelbar&quot;.</li>
</ul>
<p>* Wenn bei <code>new int[Ein paar Billionen]</code> nen <code>bad_alloc</code> fliegt ist normalerweise noch gar nix &quot;total am Anschlag&quot;, und das Programm kann normal weiterlaufen. Der Versuch z.B. in einem Bildbearbeitungsprogramm ein Bild auf die 10-fache Grösse zu skalieren sollte mMn. nicht dazu führen dass ich das Bildbearbeitungsprogramm neu starten muss wenn ich ohne Fehler weiter arbeiten möchte.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2492090</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2492090</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Sat, 02 Apr 2016 08:24:28 GMT</pubDate></item><item><title><![CDATA[Reply to Baum mit unique_ptr? on Sat, 02 Apr 2016 08:27:59 GMT]]></title><description><![CDATA[<p><strong>jb</strong> schrieb:</p>
<blockquote>
<p>Kleine Randfrage zu den Exceptions bei new</p>
<p>TyRoXx schrieb:</p>
<blockquote>
<p>happystudent schrieb:</p>
<blockquote>
<ul>
<li>Wird hier sämtlicher Speicher korrekt wieder aufgeräumt?</li>
</ul>
</blockquote>
<p>Nicht, wenn eine Exception auftritt.[...]</p>
</blockquote>
<p>Wenn bei new eine Exception auftritt, dann ist doch eh schon alles zu spät oder? In welchem Anwendungsfall interessiert mich das den?</p>
<p>Angenommen ich hab ein Programm, bei einer Allokation wird eine Exception geworfen. Meine Annahme ist die Exception wird nur geworfen da mein Rechner aktuell total am Anschlag ist und kein weiterer Speicher mehr zur Verfügung steht. Somit ist auch ein sinnvoller Programmablauf (aus meiner Sicht) nicht mehr möglich, da jede weitere Allokation auch nicht mehr möglich ist. Und somit bleibt doch nur noch der Programmcrash und das Betriebssystem räumt anschließend den Speicher auf.</p>
<p>Drei Rückfragen:<br />
(1) Behandelt ihr die mögliche Exceptions die bei &quot;new&quot; auftreten könnten?<br />
(2) Aus welchem Grund macht ihr das?<br />
(3) Gibt es dann noch einen sinnvollen Programmablauf?</p>
</blockquote>
<p>Deine Beschränkung auf SPEICHER ist javaesk.</p>
<p>Das delete ruft einen Destruktor auf, der eine im Keller stehende aus Versehen aktivierte Atombombe entschärft. Außerdem werden die Datenbankverbindungen geschlossen, damit der Server sie nicht noch sinnlose 300 Sekunden offen läßt. Und einer der Destruktoren bestellt mir eine Pizza und siehe, ich war nicht mehr hungrig.<br />
Bald wird der Baum ausgebaut und kann mehr als nur ints verwalten. Auch vielleicht DEatenbankverbindungen. new Node ruft dabei einen Konstruktor auf, der eine Datenbabnkverbindung öffnet, aber im Fehlerfall eine Exception wirft. Also muss man die Exceptions aus new doch behandeln!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2492092</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2492092</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Sat, 02 Apr 2016 08:27:59 GMT</pubDate></item><item><title><![CDATA[Reply to Baum mit unique_ptr? on Sun, 03 Apr 2016 07:37:56 GMT]]></title><description><![CDATA[<p>hustbaer &amp; volkard, vielen Dank für Eure Antworten.<br />
Ja, ich hab mich nur auf bad_alloc beschränkt. Wenn T irgendwas werfen kann (FileNotFound o.ä.), dann ist es klar das eine sinnvolle Abarbeitung im Programm weiterhin möglich ist/sein sollte.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2492159</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2492159</guid><dc:creator><![CDATA[__jb__]]></dc:creator><pubDate>Sun, 03 Apr 2016 07:37:56 GMT</pubDate></item><item><title><![CDATA[Reply to Baum mit unique_ptr? on Sun, 03 Apr 2016 15:07:00 GMT]]></title><description><![CDATA[<p>Der grösste Teil meines Beitrages gilt auch wenn es nur um <code>bad_alloc</code> geht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2492203</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2492203</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Sun, 03 Apr 2016 15:07:00 GMT</pubDate></item><item><title><![CDATA[Reply to Baum mit unique_ptr? on Sun, 03 Apr 2016 15:21:46 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>Danke schonmal für die Antworten. Ich habe den Code jetzt mal abgeändert und versucht die Vorschläge entsprechend umzusetzen:</p>
<pre><code>#include &lt;iostream&gt;
#include &lt;memory&gt;
using namespace std;

struct Node
{
	virtual int eval() = 0;
	virtual unique_ptr&lt;Node&gt; copy() = 0;
	virtual ~Node() {}
};

struct NodeValue : Node
{
	int value;
	NodeValue(int value) : value(value) {}
	virtual int eval() { return value; }
	virtual unique_ptr&lt;Node&gt; copy() { return unique_ptr&lt;Node&gt;(new NodeValue(value)); }
};

struct NodeAdd : Node
{
	unique_ptr&lt;Node&gt; left, right;
	NodeAdd(unique_ptr&lt;Node&gt; left, unique_ptr&lt;Node&gt; right) : left(move(left)), right(move(right)) {}
	virtual int eval() { return left-&gt;eval() + right-&gt;eval(); }
	virtual unique_ptr&lt;Node&gt; copy() { return unique_ptr&lt;Node&gt;(new NodeAdd(left-&gt;copy(), right-&gt;copy())); }
};

struct Func
{
	unique_ptr&lt;Node&gt; node;

	Func(unique_ptr&lt;Node&gt; node) : node(move(node)) {}
	Func(Func const &amp;other) : node(other.node-&gt;copy()) {}
	Func &amp;operator=(Func const &amp;other) { if (this != &amp;other) { node = other.node-&gt;copy(); } return *this; }
	int operator()(){ return node-&gt;eval(); }
};

void foo(Func func) // Copy
{
	Func tmp = func; // Copy asign
	std::cout &lt;&lt; tmp() &lt;&lt; &quot;\n&quot;;
}

int main()
{
	auto node = make_unique&lt;NodeAdd&gt;(make_unique&lt;NodeValue&gt;(2), make_unique&lt;NodeValue&gt;(5));

	Func func(move(node));

	foo(func);
}
</code></pre>
<p>Passt das so, oder gibt es da noch irgendwelche Probleme die ich übersehen habe?</p>
<p>Ein potentielles Problem ist wahrscheinlich das ich in der <code>copy</code> Methode nach wie vor <code>new</code> nutze, aber ich weiß nicht wie ich das vermeiden soll. Das Problem ist ja dass wenn ich <code>Node</code> als template-Parameter an <code>make_unique</code> übergebe, ich dann nicht sagen kann welchen <code>Node</code> ich jetzt erstellen will, da ich nur den Konstruktor von <code>Node</code> zur Verfügung habe (was ja so gar nicht erstellt werden kann, da pure virtual).</p>
<p>Gebe ich aber statt dessen <code>NodeAdd</code> / <code>NodeValue</code> als template Parameter an <code>make_unique</code> , stimmt der Rückgabetyp der Methode nicht mit dem geforderten Rückgabetyp der rein virtuellen Methode <code>copy</code> überein, und es kompiliert (logischerweise) nicht.</p>
<p>Anscheinend lässt sich ein smart pointer nicht wie ein raw pointer implizit in einen base pointer konvertieren... (kann mich dunkel erinnern damit schonmal Probleme gehabt zu haben).</p>
<p>Deswegen meine Frage(n): Passt das so und wie würdet ihr das oben genannte Problem angehen?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2492204</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2492204</guid><dc:creator><![CDATA[happystudent]]></dc:creator><pubDate>Sun, 03 Apr 2016 15:21:46 GMT</pubDate></item><item><title><![CDATA[Reply to Baum mit unique_ptr? on Sun, 03 Apr 2016 15:44:28 GMT]]></title><description><![CDATA[<p>Die verbleibenden <code>new</code> bekommst du so weg:</p>
<pre><code class="language-cpp">//...
    //virtual unique_ptr&lt;Node&gt; copy() { return unique_ptr&lt;Node&gt;(new NodeValue(value)); }
    virtual unique_ptr&lt;Node&gt; copy() { return make_unique&lt;NodeValue&gt;(value); } 
//...
    //virtual unique_ptr&lt;Node&gt; copy() { return unique_ptr&lt;Node&gt;(new NodeAdd(left-&gt;copy(), right-&gt;copy())); }
    virtual unique_ptr&lt;Node&gt; copy() { return make_unique&lt;NodeAdd&gt;(left-&gt;copy(), right-&gt;copy()); } 
//...
</code></pre>
<p>GCC 5.2 kompiliert das fehlerfrei, und ich gehe auch davon aus dass es standardkonform ist.</p>
<p>Diese beiden <code>new</code> sind zwar auch so unproblematisch, aber alleine schon weil ich mir über sowas gar keine Gedanken machen will, würde ich die <code>make_unique</code> Variante vorziehen.</p>
<p>ps: Hat mit deiner Frage nix zu tun, aber überleg dir ob du die Benennung der Klassen so beibehalten willst. Ich schreibe Bezeichner in Programmen gerne so wie auch zusammengesetzte Hauptwörter funktionieren. Also so dass ein Schäferhund ein Hund ist und kein Schäfer. Demnach müssten deine Klassen dann <code>ValueNode</code> und <code>AddNode</code> heissen.<br />
Muss man nicht so machen, aber ich find's angenehmer zu lesen.<br />
Ich hab' auch den Eindruck dass diese Art der Benamsung wesentlich weiter verbreitet ist als anders rum.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2492207</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2492207</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Sun, 03 Apr 2016 15:44:28 GMT</pubDate></item><item><title><![CDATA[Reply to Baum mit unique_ptr? on Sun, 03 Apr 2016 18:15:27 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>Die verbleibenden <code>new</code> bekommst du so weg:<br />
...<br />
GCC 5.2 kompiliert das fehlerfrei, und ich gehe auch davon aus dass es standardkonform ist.</p>
</blockquote>
<p>Stimmt, das kompiliert ja auch bei mir (VS 2013)... da hatte sich anscheinend nur Intellisense aufgehängt - das hat als Fehler folgendes gebracht:</p>
<p><strong>return type is not identical to nor covariant with return type &quot;std::unique_ptr&lt;Node, std::default_delete&lt;Node&gt;&gt;&quot; of overridden virtual function &quot;Node::copy&quot;</strong></p>
<p>Aber dann scheint das ja trotzdem zu funktionieren, das ist dann natürlich optimal (Merke an mich: nicht auf Intellisense verlassen sondern immer richtig kompilieren <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f921.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--clown_face"
      title=":clown:"
      alt="🤡"
    /> ).</p>
<p>hustbaer schrieb:</p>
<blockquote>
<p>ps: Hat mit deiner Frage nix zu tun, aber überleg dir ob du die Benennung der Klassen so beibehalten willst. Ich schreibe Bezeichner in Programmen gerne so wie auch zusammengesetzte Hauptwörter funktionieren. Also so dass ein Schäferhund ein Hund ist und kein Schäfer. Demnach müssten deine Klassen dann <code>ValueNode</code> und <code>AddNode</code> heissen.</p>
</blockquote>
<p>Ja das hatte ich mir auch schonmal überlegt, aber das Problem ist dann dass die im Intellisense nicht mehr zusammen aufgelistet werden... Also ich find es praktisch wenn man dann z.B. alle Nodes hintereinander in der Autocomplete Liste hat.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2492227</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2492227</guid><dc:creator><![CDATA[happystudent]]></dc:creator><pubDate>Sun, 03 Apr 2016 18:15:27 GMT</pubDate></item><item><title><![CDATA[Reply to Baum mit unique_ptr? on Sun, 03 Apr 2016 22:24:45 GMT]]></title><description><![CDATA[<p>Hattest du vielleicht versucht als Returntyp <code>unique_ptr&lt;NodeValue&gt;</code> zu verwenden?</p>
<p>Das geht natürlich nicht, weil <code>virtual</code> sich nicht darum kümmert was per user-defined conversion konvertierbar ist, sondern nur &quot;eingebaute&quot; Konvertierungen von Zeigern bzw. Referenzen erlaubt.<br />
<code>unique_ptr</code> bietet die Konvertierung allerdings implizit an, was der Grund ist warum es mit <code>unique_ptr&lt;Node&gt;</code> dann geht.</p>
<p>Ansonsten ja, immer richtig kompilieren. Intellisense verwendet ein anderes Frontend als der eigentliche Compiler.</p>
<p>happystudent schrieb:</p>
<blockquote>
<p>Ja das hatte ich mir auch schonmal überlegt, aber das Problem ist dann dass die im Intellisense nicht mehr zusammen aufgelistet werden... Also ich find es praktisch wenn man dann z.B. alle Nodes hintereinander in der Autocomplete Liste hat.</p>
</blockquote>
<p>Ja, ich kenne das Argument, war für mich schliesslich selbst ein Grund es ne Zeitlang so wie du zu machen. Bin jetzt aber der Meinung dass die andere Variante besser ist. Weil man einerseits die Bedeutung eines Klassennamen nicht &quot;dekodieren&quot; muss, sondern oft sofort versteht was gemeint ist, und weil es andrerseits einfach die Variant ist die häufiger verwendet wird. (Und gegen den Strom zu schwimmen zahl sich mMn. nur aus wenn man dadurch einen echten Vorteil hat.)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2492240</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2492240</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Sun, 03 Apr 2016 22:24:45 GMT</pubDate></item><item><title><![CDATA[Reply to Baum mit unique_ptr? on Mon, 04 Apr 2016 18:28:15 GMT]]></title><description><![CDATA[<p>In dem Fall braucht man die konkreten Klassennamen sowieso selten. Es gibt vielleicht 1-2 Stellen, wo ein NodeAdd erstellt wird, ansonsten muss man den Namen nicht kennen. Dann kann er auch gleich AddNode heißen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2492305</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2492305</guid><dc:creator><![CDATA[Mechanics]]></dc:creator><pubDate>Mon, 04 Apr 2016 18:28:15 GMT</pubDate></item><item><title><![CDATA[Reply to Baum mit unique_ptr? on Wed, 06 Apr 2016 20:26:51 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>Hattest du vielleicht versucht als Returntyp <code>unique_ptr&lt;NodeValue&gt;</code> zu verwenden?</p>
</blockquote>
<p>Ne, war schon <code>unique_ptr&lt;Node&gt;</code> , aber die Meldung war nach kompilieren, Projekt schließen und wieder öffnen dann auch weg. Intellisense reagiert teilweise auch recht langsam auf Änderungen...</p>
<p>hustbaer schrieb:</p>
<blockquote>
<p>Ja, ich kenne das Argument, war für mich schliesslich selbst ein Grund es ne Zeitlang so wie du zu machen. Bin jetzt aber der Meinung dass die andere Variante besser ist.</p>
</blockquote>
<p>Mechanics schrieb:</p>
<blockquote>
<p>In dem Fall braucht man die konkreten Klassennamen sowieso selten. Es gibt vielleicht 1-2 Stellen, wo ein NodeAdd erstellt wird, ansonsten muss man den Namen nicht kennen. Dann kann er auch gleich AddNode heißen.</p>
</blockquote>
<p>Stimmt auch wieder, werd das nochmal überdenken.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2492497</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2492497</guid><dc:creator><![CDATA[happystudent]]></dc:creator><pubDate>Wed, 06 Apr 2016 20:26:51 GMT</pubDate></item><item><title><![CDATA[Reply to Baum mit unique_ptr? on Wed, 06 Apr 2016 23:50:24 GMT]]></title><description><![CDATA[<p>Wobei: Das wichtigste bei Benamsung und allg. &quot;Style-Konventionen&quot; ist mMn. dass man es (wenigstens) pro Projekt einheitlich durchzieht.<br />
Zumindest in langlebigen Projekten die häufiger erweitert/gändert bzw. allgemein &quot;gewartet&quot; werden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2492507</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2492507</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Wed, 06 Apr 2016 23:50:24 GMT</pubDate></item></channel></rss>