<?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[Regel der Großen Drei aushebeln?!]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>die Regel der großen Drei besagt, dass man, falls man einen der 3 selbst definiert auch auf jedenfall die anderen beiden selbst definieren muss.<br />
Ich spreche natürlich von Kopierkonstruktor, Zuweisungsoperator und Destruktor.</p>
<p>Aber wird diese Regeln nicht von Smartpointern ausgehebelt, unter gewissen Umständen?!</p>
<p>Folgendes Beispiel dazu:</p>
<pre><code>#include &lt;iostream&gt;
#include &lt;fstream&gt;
#include &lt;sstream&gt;
#include &lt;memory&gt;

class Base
{
	int dummy;

public:
	virtual std::unique_ptr&lt;Base&gt; clone() const = 0;
};

class DummyDerive : public Base
{
	float dummies[10];

public:
	virtual std::unique_ptr&lt;Base&gt; clone() const
	{
		std::unique_ptr&lt;DummyDerive&gt; tmp(new DummyDerive);
		return std::move(tmp);
	}
};

class Derive : public Base
{
	std::unique_ptr&lt;Base&gt; ptr;

public:
	Derive()
		: ptr(new DummyDerive)
	{ }

	Derive(Derive const&amp; d)
	{
		this-&gt;ptr = std::move(d.clone());
	}

	Derive&amp; operator=(Derive const&amp; d)
	{
		this-&gt;swap(d);
		return *this;
	}

	void swap(Derive d)
	{
		std::swap(this-&gt;ptr, d.ptr);
	}

public:
	virtual std::unique_ptr&lt;Base&gt; clone() const // Dummy Implementierung
	{
		std::unique_ptr&lt;Base&gt; null;
		return null;
	}
};
// Code ist unter Visual C++ 2012 fehlerfrei kompilierbar
</code></pre>
<p>Wie ihr seht geht es hier um Fälle, wenn eine Klasse Smartpointer auf Klassenhierarchien hat. Gelöscht werden muss nichts, denn das erledigt der smarte Zeiger. Nur das Kopieren stellt sich mehr doer weniger als Problem dar (je nachdem was man wie hat, im aktuellen Projekt war es schon ein dicker Hund).</p>
<p>Aber genau sowas widersprucht doch der Regel der Großen 3</p>
<p>Oder liege ich irgendwo falsch? (Denn genauso fühlt es sich an, ohne eigenen Destruktor)</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/313071/regel-der-großen-drei-aushebeln</link><generator>RSS for Node</generator><lastBuildDate>Sun, 02 Aug 2026 08:35:41 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/313071.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 21 Jan 2013 09:08:32 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Regel der Großen Drei aushebeln?! on Mon, 21 Jan 2013 09:08:32 GMT]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>die Regel der großen Drei besagt, dass man, falls man einen der 3 selbst definiert auch auf jedenfall die anderen beiden selbst definieren muss.<br />
Ich spreche natürlich von Kopierkonstruktor, Zuweisungsoperator und Destruktor.</p>
<p>Aber wird diese Regeln nicht von Smartpointern ausgehebelt, unter gewissen Umständen?!</p>
<p>Folgendes Beispiel dazu:</p>
<pre><code>#include &lt;iostream&gt;
#include &lt;fstream&gt;
#include &lt;sstream&gt;
#include &lt;memory&gt;

class Base
{
	int dummy;

public:
	virtual std::unique_ptr&lt;Base&gt; clone() const = 0;
};

class DummyDerive : public Base
{
	float dummies[10];

public:
	virtual std::unique_ptr&lt;Base&gt; clone() const
	{
		std::unique_ptr&lt;DummyDerive&gt; tmp(new DummyDerive);
		return std::move(tmp);
	}
};

class Derive : public Base
{
	std::unique_ptr&lt;Base&gt; ptr;

public:
	Derive()
		: ptr(new DummyDerive)
	{ }

	Derive(Derive const&amp; d)
	{
		this-&gt;ptr = std::move(d.clone());
	}

	Derive&amp; operator=(Derive const&amp; d)
	{
		this-&gt;swap(d);
		return *this;
	}

	void swap(Derive d)
	{
		std::swap(this-&gt;ptr, d.ptr);
	}

public:
	virtual std::unique_ptr&lt;Base&gt; clone() const // Dummy Implementierung
	{
		std::unique_ptr&lt;Base&gt; null;
		return null;
	}
};
// Code ist unter Visual C++ 2012 fehlerfrei kompilierbar
</code></pre>
<p>Wie ihr seht geht es hier um Fälle, wenn eine Klasse Smartpointer auf Klassenhierarchien hat. Gelöscht werden muss nichts, denn das erledigt der smarte Zeiger. Nur das Kopieren stellt sich mehr doer weniger als Problem dar (je nachdem was man wie hat, im aktuellen Projekt war es schon ein dicker Hund).</p>
<p>Aber genau sowas widersprucht doch der Regel der Großen 3</p>
<p>Oder liege ich irgendwo falsch? (Denn genauso fühlt es sich an, ohne eigenen Destruktor)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2291816</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2291816</guid><dc:creator><![CDATA[Skym0sh0]]></dc:creator><pubDate>Mon, 21 Jan 2013 09:08:32 GMT</pubDate></item><item><title><![CDATA[Reply to Regel der Großen Drei aushebeln?! on Mon, 21 Jan 2013 09:16:12 GMT]]></title><description><![CDATA[<p>Die Regel ist mehr so eine Richtlinie, als ein Gesetz. Steht ja auch explizit drin, wo Du auch nachschaust.</p>
<p>Außerdem ist sie wesentlich schärfer mit &quot;Wenn ein Destruktor gebraucht wird, dann vermutlich auch die anderen beiden&quot;.</p>
<p>Außerdem sollte man die anderen beiden viel öfter verbieten, als sich eine unintuitive Semantik auszudenken.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2291817</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2291817</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Mon, 21 Jan 2013 09:16:12 GMT</pubDate></item><item><title><![CDATA[Reply to Regel der Großen Drei aushebeln?! on Mon, 21 Jan 2013 09:14:23 GMT]]></title><description><![CDATA[<p>Base braucht einen virtuellen Destruktor, sonst ruft der Destruktor des Smart-Pointers immer den falschen auf.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2291818</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2291818</guid><dc:creator><![CDATA[seldon]]></dc:creator><pubDate>Mon, 21 Jan 2013 09:14:23 GMT</pubDate></item><item><title><![CDATA[Reply to Regel der Großen Drei aushebeln?! on Mon, 21 Jan 2013 09:15:07 GMT]]></title><description><![CDATA[<p>Ok, und es zielt in Richtung Speicherverwaltung ab?</p>
<p>Obiger Code ist damit vollkommen richtig? (und als Beispielcode wie gewohnt vollkommen sinnlos xD)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2291819</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2291819</guid><dc:creator><![CDATA[Skym0sh0]]></dc:creator><pubDate>Mon, 21 Jan 2013 09:15:07 GMT</pubDate></item><item><title><![CDATA[Reply to Regel der Großen Drei aushebeln?! on Mon, 21 Jan 2013 11:04:55 GMT]]></title><description><![CDATA[<p>Immer das selbe Problem mit ad hoc reingetippten Beispielen:</p>
<pre><code class="language-cpp">Derive&amp; operator=(Derive const&amp; d) 
     { 
         this-&gt;swap(d); 
         return *this; 
     }
</code></pre>
<p>Das <code>const&amp;</code> muss weg.</p>
<p>EDIT:</p>
<pre><code class="language-cpp">void swap(Derive d) 
     { 
         std::swap(this-&gt;ptr, d.ptr); 
     }
</code></pre>
<p>Das compiliert und lässt sich auch aufrufen und alles, macht aber nicht das was man von einer swap() Funktion normalerweise erwarten würde...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2291862</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2291862</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Mon, 21 Jan 2013 11:04:55 GMT</pubDate></item><item><title><![CDATA[Reply to Regel der Großen Drei aushebeln?! on Mon, 21 Jan 2013 11:07:46 GMT]]></title><description><![CDATA[<p>Haha, genau umgekehrt, ja hast Recht.</p>
<p>Der Kopf des Zuweisungsoperator muss eine Kopie erwarten und die swap Funktion eine non-const Referenz <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2291866</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2291866</guid><dc:creator><![CDATA[Skym0sh0]]></dc:creator><pubDate>Mon, 21 Jan 2013 11:07:46 GMT</pubDate></item></channel></rss>