<?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[move constructor]]></title><description><![CDATA[<p>Hallo,</p>
<p>kann mir jemand zeigen wie ich hier den copy constructor/asignment operator mit std::move und rvalue richtig implementiere?</p>
<p>LG</p>
<pre><code>class IntVec {
public:
	int *arr;
	int size;

public:
	IntVec (int size_): size(size_) {
		arr = new int[size_];
	}

	IntVec (const IntVec &amp;rhs) {

		size = rhs.size;

		for(int i = 0; i &lt; size; i++) {
			arr[i] = rhs.arr[i];
		}
	}

	IntVec &amp;operator=(const IntVec &amp;rhs) {
		if (this != &amp;rhs)
		{
			if (size != rhs.size)
			{
				delete [] arr;
				arr = new int[rhs.size];
				size = rhs.size;
			}
			std::copy(rhs.arr, rhs.arr + size, arr);
		}
		return *this;
	}

	IntVec (const IntVec &amp;&amp;rhs) {

		....
	}

	IntVec &amp;operator=(const IntVec &amp;&amp;rhs) {
		IntVec lhs = std::move(rhs);
		*this = lhs;

		return *this;
	}
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/321251/move-constructor</link><generator>RSS for Node</generator><lastBuildDate>Tue, 21 Jul 2026 17:00:07 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/321251.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 29 Oct 2013 20:52:53 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to move constructor on Tue, 29 Oct 2013 20:52:53 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>kann mir jemand zeigen wie ich hier den copy constructor/asignment operator mit std::move und rvalue richtig implementiere?</p>
<p>LG</p>
<pre><code>class IntVec {
public:
	int *arr;
	int size;

public:
	IntVec (int size_): size(size_) {
		arr = new int[size_];
	}

	IntVec (const IntVec &amp;rhs) {

		size = rhs.size;

		for(int i = 0; i &lt; size; i++) {
			arr[i] = rhs.arr[i];
		}
	}

	IntVec &amp;operator=(const IntVec &amp;rhs) {
		if (this != &amp;rhs)
		{
			if (size != rhs.size)
			{
				delete [] arr;
				arr = new int[rhs.size];
				size = rhs.size;
			}
			std::copy(rhs.arr, rhs.arr + size, arr);
		}
		return *this;
	}

	IntVec (const IntVec &amp;&amp;rhs) {

		....
	}

	IntVec &amp;operator=(const IntVec &amp;&amp;rhs) {
		IntVec lhs = std::move(rhs);
		*this = lhs;

		return *this;
	}
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2363752</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2363752</guid><dc:creator><![CDATA[jeff1]]></dc:creator><pubDate>Tue, 29 Oct 2013 20:52:53 GMT</pubDate></item><item><title><![CDATA[Reply to move constructor on Tue, 29 Oct 2013 21:10:00 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">class IntVec {
public:
    int *arr;
    int size;

public:
    explicit IntVec (int size_)
        : arr( new int[size_]{} ), size(size_) {
    }

    IntVec (const IntVec &amp;rhs)
        : arr( new int[rhs.size] ), size(rhs.size) {
        std::copy(rhs.arr, rhs.arr+size, arr );
    }

    IntVec (IntVec &amp;&amp;rhs) noexcept
        : arr( rhs.arr ), size(rhs.size) {
        rhs.arr = nullptr;
        rhs.size = 0;
    }

    ~IntVec () noexcept {
        delete [] arr;
    }

    IntVec &amp;operator=(const IntVec &amp;rhs) {
        IntVec tmp = rhs;
        swap( tmp );
        return *this;
    }

    IntVec &amp;operator=(IntVec &amp;&amp;rhs) noexcept {
        IntVec tmp = std::move(rhs);
        swap( tmp );
        return *this;
    }

    void swap(IntVec &amp;other) {
        using std::swap;
        swap( arr, other.arr );
        swap( size, other.size );
    }

};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2363761</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2363761</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Tue, 29 Oct 2013 21:10:00 GMT</pubDate></item><item><title><![CDATA[Reply to move constructor on Tue, 29 Oct 2013 21:31:17 GMT]]></title><description><![CDATA[<p>Ist das ein reeles Beispiel oder geht es dir nur um das Prinzip? In der Praxis würde man einen vector nehmen und könnte sich die ganzen selbst definierten Operatoren sparen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2363767</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2363767</guid><dc:creator><![CDATA[TNA]]></dc:creator><pubDate>Tue, 29 Oct 2013 21:31:17 GMT</pubDate></item><item><title><![CDATA[Reply to move constructor on Tue, 29 Oct 2013 21:54:24 GMT]]></title><description><![CDATA[<p>es geht mir ums prinzip...klar ich kenne wohl std::vector.</p>
<p>warum braucht IntVec (IntVec &amp;&amp;rhs) kein std::move?</p>
<p>muss ich eine selbstzuweisung nicht mit if(this != &amp;rhs) abfangen?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2363779</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2363779</guid><dc:creator><![CDATA[jeff1]]></dc:creator><pubDate>Tue, 29 Oct 2013 21:54:24 GMT</pubDate></item><item><title><![CDATA[Reply to move constructor on Tue, 29 Oct 2013 21:57:13 GMT]]></title><description><![CDATA[<p>camper schrieb:</p>
<blockquote>
<pre><code class="language-cpp">[...]
    IntVec &amp;operator=(const IntVec &amp;rhs) {
        IntVec tmp = rhs;
        swap( tmp );
        return *this;
    }
 
    IntVec &amp;operator=(IntVec &amp;&amp;rhs) noexcept {
        IntVec tmp = std::move(rhs);
        swap( tmp );
        return *this;
    }
[...]
</code></pre>
</blockquote>
<p>Da kann man auch</p>
<pre><code class="language-cpp">IntVec&amp; operator = (IntVec other) {
        swap( other );
        return *this;
    }
</code></pre>
<p>schreiben. Man spart sich die doppelte Definition und es passiert das gleiche.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2363780</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2363780</guid><dc:creator><![CDATA[Marthog]]></dc:creator><pubDate>Tue, 29 Oct 2013 21:57:13 GMT</pubDate></item><item><title><![CDATA[Reply to move constructor on Tue, 29 Oct 2013 22:11:39 GMT]]></title><description><![CDATA[<p>was macht</p>
<pre><code>IntVec tmp = std::move(rhs);
</code></pre>
<p>genau?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2363785</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2363785</guid><dc:creator><![CDATA[jeff1]]></dc:creator><pubDate>Tue, 29 Oct 2013 22:11:39 GMT</pubDate></item><item><title><![CDATA[Reply to move constructor on Tue, 29 Oct 2013 22:13:37 GMT]]></title><description><![CDATA[<p>und warum wird hier rhs.arr und rhs.size auf 0 gesetzt?</p>
<pre><code>IntVec (IntVec &amp;&amp;rhs) noexcept 
        : arr( rhs.arr ), size(rhs.size) { 
        rhs.arr = nullptr; 
        rhs.size = 0; 
    }
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2363787</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2363787</guid><dc:creator><![CDATA[jeff1]]></dc:creator><pubDate>Tue, 29 Oct 2013 22:13:37 GMT</pubDate></item><item><title><![CDATA[Reply to move constructor on Tue, 29 Oct 2013 22:22:14 GMT]]></title><description><![CDATA[<p>jeff1 schrieb:</p>
<blockquote>
<p>und warum wird hier rhs.arr und rhs.size auf 0 gesetzt?</p>
</blockquote>
<p>Weil irgendwann der Destruktor von rhs aufgerufen wird und man nicht mit einem dangling pointer hantieren möchte.<br />
Size auf 0 setzen ist streng genommen nicht nötig.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2363790</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2363790</guid><dc:creator><![CDATA[nullptr]]></dc:creator><pubDate>Tue, 29 Oct 2013 22:22:14 GMT</pubDate></item><item><title><![CDATA[Reply to move constructor on Wed, 30 Oct 2013 07:26:17 GMT]]></title><description><![CDATA[<p>Edit: gelöscht, hatte mich verlesen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2363815</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2363815</guid><dc:creator><![CDATA[TNA]]></dc:creator><pubDate>Wed, 30 Oct 2013 07:26:17 GMT</pubDate></item><item><title><![CDATA[Reply to move constructor on Wed, 30 Oct 2013 07:52:37 GMT]]></title><description><![CDATA[<p>jeff1 schrieb:</p>
<blockquote>
<p>was macht</p>
<pre><code>IntVec tmp = std::move(rhs);
</code></pre>
<p>genau?</p>
</blockquote>
<p>move(rhs) gibt eine rvalue-Referenz auf rhs zurück, so dass tmp über den Move-Konstruktor erzeugt wird. Das kann bei üblicher Implementierung bedeuten, dass rhs danach leer ist. rhs ist ein lvalue, ohne move würde also der Kopierkonstruktor gerufen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2363818</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2363818</guid><dc:creator><![CDATA[Bashar]]></dc:creator><pubDate>Wed, 30 Oct 2013 07:52:37 GMT</pubDate></item><item><title><![CDATA[Reply to move constructor on Wed, 30 Oct 2013 09:15:28 GMT]]></title><description><![CDATA[<p>Marthog schrieb:</p>
<blockquote>
<p>camper schrieb:</p>
<blockquote>
<pre><code class="language-cpp">[...]
    IntVec &amp;operator=(const IntVec &amp;rhs) {
        IntVec tmp = rhs;
        swap( tmp );
        return *this;
    }
 
    IntVec &amp;operator=(IntVec &amp;&amp;rhs) noexcept {
        IntVec tmp = std::move(rhs);
        swap( tmp );
        return *this;
    }
[...]
</code></pre>
</blockquote>
<p>Da kann man auch</p>
<pre><code class="language-cpp">IntVec&amp; operator = (IntVec other) {
        swap( other );
        return *this;
    }
</code></pre>
<p>schreiben. Man spart sich die doppelte Definition und es passiert das gleiche.</p>
</blockquote>
<p>Das ist dann alledings kein <em>move assignment operator</em> mehr. Was in C++11 durchaus einen Unterschied macht. Speziell bei der Deklaration von impliziten move assignment Operatoren von Klassen, die ein <code>IntVec</code> als Member haben.</p>
<p>Tatsächlich ist das ein defect in C++11 und meine Anmerkung hier nur der Vollständigkeit halber. *</p>
<p>FW</p>
<p>* d.h. ich möchte diesen Thread nicht durch eine ellenlange Diskussion über Sprachfeinheiten ersetzen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2363825</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2363825</guid><dc:creator><![CDATA[Furble Wurble]]></dc:creator><pubDate>Wed, 30 Oct 2013 09:15:28 GMT</pubDate></item><item><title><![CDATA[Reply to move constructor on Wed, 30 Oct 2013 18:32:33 GMT]]></title><description><![CDATA[<blockquote>
<p>move(rhs) gibt eine rvalue-Referenz auf rhs zurück, so dass tmp über den Move-Konstruktor erzeugt wird. Das kann bei üblicher Implementierung bedeuten, dass rhs danach leer ist.</p>
</blockquote>
<p>woher soll der user wissen ob der copy oder move constructor augerufen wird? im zweiten fall wird der operand rechts des zuweisungs operators ja NULL...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2363970</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2363970</guid><dc:creator><![CDATA[jeff1]]></dc:creator><pubDate>Wed, 30 Oct 2013 18:32:33 GMT</pubDate></item><item><title><![CDATA[Reply to move constructor on Wed, 30 Oct 2013 19:13:36 GMT]]></title><description><![CDATA[<p>Bei RValues wird der Movekonstruktor aufgerufen, bei LValues der Copykonstruktor.<br />
RValues sind z.B. std::move(lvalue), Konstruktoraufrufe.<br />
Bei den temporären Objekten, die entstehen, wenn man eine Funktion void bar(foo f), so aufruft: bar(foo(1, 'a')), ist das egal, weil sie eh nicht lange leben.<br />
Da ist das eine Optimierung.<br />
Bspw. std::vector muss im Copyctor alle n Elemente von a nach b kopieren, beim move hingegen nur einen Pointer versetzen (wie in deinem Code).<br />
Dass das viel schneller ist, sollte klar sein.<br />
Hat man ein LValue und muss man es an einen anderen Ort haben und braucht man es danach nicht mehr, nutzt man std::move um das zum LValue zu machen (move ist im Prinzip nur ein cast!).<br />
Das hat man z.B. in der Initialisierungsliste eines Konstruktors:<br />
foo(costly_copyable c) c_(std::move(c)) {}<br />
Da man c danach nicht mehr braucht, ist der State egal. move bietet sich hier an und ist schneller.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2363975</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2363975</guid><dc:creator><![CDATA[Nathan]]></dc:creator><pubDate>Wed, 30 Oct 2013 19:13:36 GMT</pubDate></item><item><title><![CDATA[Reply to move constructor on Thu, 31 Oct 2013 09:22:59 GMT]]></title><description><![CDATA[<p>jeff1 schrieb:</p>
<blockquote>
<p>woher soll der user wissen ob der copy oder move constructor augerufen wird?</p>
</blockquote>
<p>Schau Dir mal die Referenz-Initialisierungs- und Überladungs-Regeln an, die dieses Verhalten erklären:</p>
<pre><code class="language-cpp">void senke(const int &amp;  lref); // #1
void senke(      int &amp;&amp; rref); // #2

int quelle() {
    return 42;
}

const int&amp; dings() {
    static const int foo = 29;
    return foo;
}

int main() {
    int j = 23;
    senke(j);            // ruft #1 auf, lref ist dann ein Synonym für j
    senke(dings());      // ruft #1 auf, lref ist dann ein Synonym für foo
    senke(j+0);          // ruft #2 auf, rref bezieht sich auf einen temporären int
    senke(17);           // ruft #2 auf, rref bezieht sich auf einen temporären int
    senke(quelle());     // ruft #2 auf, rref bezieht sich auf einen temporären int
    senke(std::move(j)); // ruft #2 auf, rref bezieht sich auf j
    return 0;
}
</code></pre>
<p>Lässt man die Rvalue-Referenz-Überladung (#2) weg, dann wird in allen Fällen hier #1 aufgerufen.</p>
<p>Die gleiche Überladung (so wie bei senke) kannst Du jetzt auch bei Konstruktoren und Zuweisungsoperatoren machen.</p>
<p>Der Witz an der ganzen Sache ist, dass eine frisch initialisierte Rvalue-Referenz sich immer nur auf etwas bezieht, was keinen mehr interessiert -- entweder, weil es ein temporäres Objekt war und kein anderer einen Weg hat, sich auf dieses noch zu beziehen, oder weil der Benutzer explizit sein Desinteresse am Zustand des Objekts (z.B. mit std::move) bekundet hat. Die Objekte, auf die sich Rvalue-Referenz-Parameter beziehen, darf man also verändern, ohne dass es jemanden stören würde. So gesehen, hätte man auch <code>std::move</code> in <code>std::i_dont_care_about_this_object_anymore</code> umbenennen können. Mehr macht das <code>std::move</code> nicht. Es ist nur dazu da, dass man als Nutzer sagen kann, dass einem ein eventuell veränderter Zustand des Objekts egal ist. Aber es wird typischerweise für Move-Semantics verwendet. Es sagt dem Compiler, dass es OK ist, statt des Kopierkonstruktors einen Movekonstruktor zu verwenden (falls es einen solchen gibt).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2364053</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2364053</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Thu, 31 Oct 2013 09:22:59 GMT</pubDate></item></channel></rss>