<?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[C++0x: Forcieren des Move-Konstruktors]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>in manchen Fällen, weiß man ja, dass ein Objekt nach einem bestimmten<br />
Zeitpunkt nicht mehr benötigt wird. Die letzte Kopie kann folglich mit Hilfe<br />
des Move-Konstruktors gemacht werden.<br />
Diese Information möchte ich dem Compiler explizit mitgeben.<br />
Deswegen habe ich mir überlegt einen expliziten cast zu machen:</p>
<pre><code class="language-cpp">#include&lt;vector&gt;
#include&lt;iostream&gt;

class A {
public:
        A(){}
        A(const A&amp;){
                std::cout &lt;&lt; &quot;copy&quot; &lt;&lt; std::endl;
        }
        A(A&amp;&amp; a){
                std::cout &lt;&lt; &quot;move&quot; &lt;&lt; std::endl;
        }
};

int main()
{
        A a1;
        A a2;
        std::vector&lt;A&gt; vec;
        vec.reserve(2);
        vec.push_back(a1); // Hier wird der Copy-Kontruktor aufgerufen
        vec.push_back(static_cast&lt;A&amp;&amp;&gt;(a2)); // Hier wird der Move-Kontruktor aufgerufen
        return 0;
}
</code></pre>
<p>Es scheint auch einwandfrei zu funktionieren:</p>
<blockquote>
<p>copy<br />
move</p>
</blockquote>
<p>Allerdings weiß ich nicht, ob das so (nach Standard C++0x) erlaubt ist.<br />
Kann ich sowas verwenden?<br />
Muss ich eventuell irgendwas spezielles beachten? (abgesehen davon, dass das Ursprungsobjekt 'kaputt' ist)</p>
<p>Gruß,<br />
XSpille</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/281956/c-0x-forcieren-des-move-konstruktors</link><generator>RSS for Node</generator><lastBuildDate>Sun, 23 Aug 2026 10:34:52 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/281956.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 11 Feb 2011 02:56:27 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to C++0x: Forcieren des Move-Konstruktors on Fri, 11 Feb 2011 02:56:27 GMT]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>in manchen Fällen, weiß man ja, dass ein Objekt nach einem bestimmten<br />
Zeitpunkt nicht mehr benötigt wird. Die letzte Kopie kann folglich mit Hilfe<br />
des Move-Konstruktors gemacht werden.<br />
Diese Information möchte ich dem Compiler explizit mitgeben.<br />
Deswegen habe ich mir überlegt einen expliziten cast zu machen:</p>
<pre><code class="language-cpp">#include&lt;vector&gt;
#include&lt;iostream&gt;

class A {
public:
        A(){}
        A(const A&amp;){
                std::cout &lt;&lt; &quot;copy&quot; &lt;&lt; std::endl;
        }
        A(A&amp;&amp; a){
                std::cout &lt;&lt; &quot;move&quot; &lt;&lt; std::endl;
        }
};

int main()
{
        A a1;
        A a2;
        std::vector&lt;A&gt; vec;
        vec.reserve(2);
        vec.push_back(a1); // Hier wird der Copy-Kontruktor aufgerufen
        vec.push_back(static_cast&lt;A&amp;&amp;&gt;(a2)); // Hier wird der Move-Kontruktor aufgerufen
        return 0;
}
</code></pre>
<p>Es scheint auch einwandfrei zu funktionieren:</p>
<blockquote>
<p>copy<br />
move</p>
</blockquote>
<p>Allerdings weiß ich nicht, ob das so (nach Standard C++0x) erlaubt ist.<br />
Kann ich sowas verwenden?<br />
Muss ich eventuell irgendwas spezielles beachten? (abgesehen davon, dass das Ursprungsobjekt 'kaputt' ist)</p>
<p>Gruß,<br />
XSpille</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2019435</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2019435</guid><dc:creator><![CDATA[XSpille]]></dc:creator><pubDate>Fri, 11 Feb 2011 02:56:27 GMT</pubDate></item><item><title><![CDATA[Reply to C++0x: Forcieren des Move-Konstruktors on Fri, 11 Feb 2011 04:28:37 GMT]]></title><description><![CDATA[<p>XSpille schrieb:</p>
<blockquote>
<p>Allerdings weiß ich nicht, ob das so (nach Standard C++0x) erlaubt ist.<br />
Kann ich sowas verwenden?</p>
</blockquote>
<p>Ja, das ist korrekt so. Allerdings ist dafür das Funktionstemplate std::move aus dem utility-Header gedacht:</p>
<pre><code class="language-cpp">vectory&lt;string&gt; vec;
string foo = ...;
foo += ...;
vec.push_back(std::move(foo));
</code></pre>
<p>std::move wird aber genau denselben Cast durchführen.</p>
<p>XSpille schrieb:</p>
<blockquote>
<p>Muss ich eventuell irgendwas spezielles beachten?</p>
</blockquote>
<p>Nö. Je nachdem, was der Move-Konstruktor anstellt, wird sich das Ursprungsobjekt in einem anderen Zustand befinden. Es ist wenigstens fehlerfrei zerstörbar (also immer noch &quot;gültig&quot; zu einem gewissen Grad). Von den meisten Klassen, die einen Zuweisungsoperator bieten, würde man auch erwarten, dass sich ein neuer Wert einem solchen Objekt immer noch zuweisen lässt. Alles weitere ist Sache des Klassendesigners. Er kann natürlich weitere Garantien darüber machen, was innerhalb eines Move-Konstruktors eigentlich passiert und welche Operationen danach noch durchgeführt werden können. Beispielsweise jst klar, dass ein moved-from unique_ptr-Objekt ein Nullzeiger speichern wird.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2019438</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2019438</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Fri, 11 Feb 2011 04:28:37 GMT</pubDate></item><item><title><![CDATA[Reply to C++0x: Forcieren des Move-Konstruktors on Fri, 11 Feb 2011 07:05:45 GMT]]></title><description><![CDATA[<p>Danke für die ausführliche Antwort krümelkacker <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/2019447</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2019447</guid><dc:creator><![CDATA[XSpille]]></dc:creator><pubDate>Fri, 11 Feb 2011 07:05:45 GMT</pubDate></item><item><title><![CDATA[Reply to C++0x: Forcieren des Move-Konstruktors on Fri, 11 Feb 2011 07:25:37 GMT]]></title><description><![CDATA[<p>Wie kann ich denn das move für eine map forcieren?</p>
<pre><code class="language-cpp">int main()
{
        A a1;
        A a2;
        std::map&lt;int, A&gt; map;
        map[0] = std::move(a1);
        std::cout &lt;&lt; &quot;---&quot; &lt;&lt; std::endl;
        map.insert(std::pair&lt;int, A&gt;(1, std::move(a2)));
        //map.insert(std::move(std::pair&lt;int, A&gt;(1, std::move(a2)))); // bringt auch nichts...
        return 0;
}
</code></pre>
<blockquote>
<p>move<br />
copy<br />
---<br />
move<br />
move<br />
copy</p>
</blockquote>
<p>Ist da beim gcc 4.5.2 etwas noch nicht fertig implementiert, geht es<br />
gar nicht oder welche Änderung muss ich machen?</p>
<p>Gruß,<br />
XSpille</p>
<p>EDIT:<br />
Natürlich kann ich als value nen Zeiger benutzen:<br />
Dieser müsste jedoch (ohne wrappen in Smart-Pointer) manuell zerstört werden...</p>
<pre><code class="language-cpp">std::map&lt;int, A*&gt; map;
        map[0] = new A(std::move(a1));
        std::cout &lt;&lt; &quot;---&quot; &lt;&lt; std::endl;
        map.insert(std::pair&lt;int, A*&gt;(1, new A(std::move(a2))));
</code></pre>
<blockquote>
<p>move<br />
---<br />
move</p>
</blockquote>
<p>Aber geht es auch anders?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2019451</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2019451</guid><dc:creator><![CDATA[XSpille]]></dc:creator><pubDate>Fri, 11 Feb 2011 07:25:37 GMT</pubDate></item><item><title><![CDATA[Reply to C++0x: Forcieren des Move-Konstruktors on Fri, 11 Feb 2011 07:50:12 GMT]]></title><description><![CDATA[<p>Probier mal mit pair&lt;int const, A&gt; bzw. einfach map&lt;&gt;::value_type.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2019460</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2019460</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Fri, 11 Feb 2011 07:50:12 GMT</pubDate></item><item><title><![CDATA[Reply to C++0x: Forcieren des Move-Konstruktors on Fri, 11 Feb 2011 08:00:05 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>Probier mal mit pair&lt;int const, A&gt; bzw. einfach map&lt;&gt;::value_type.</p>
</blockquote>
<p>Geht leider auch nicht <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /><br />
Danke trotzdem für diese Idee!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2019465</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2019465</guid><dc:creator><![CDATA[XSpille]]></dc:creator><pubDate>Fri, 11 Feb 2011 08:00:05 GMT</pubDate></item><item><title><![CDATA[Reply to C++0x: Forcieren des Move-Konstruktors on Fri, 11 Feb 2011 08:11:35 GMT]]></title><description><![CDATA[<p>mag sein, dass std::pair von libstdc++ noch nicht auf dem aktuellen Stand ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2019469</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2019469</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Fri, 11 Feb 2011 08:11:35 GMT</pubDate></item><item><title><![CDATA[Reply to C++0x: Forcieren des Move-Konstruktors on Fri, 11 Feb 2011 08:15:12 GMT]]></title><description><![CDATA[<p>vc10 kompilierts zu</p>
<pre><code>move
move
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2019471</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2019471</guid><dc:creator><![CDATA[brotbernd]]></dc:creator><pubDate>Fri, 11 Feb 2011 08:15:12 GMT</pubDate></item><item><title><![CDATA[Reply to C++0x: Forcieren des Move-Konstruktors on Fri, 11 Feb 2011 08:29:28 GMT]]></title><description><![CDATA[<p>Okay...</p>
<p>gcc 4.6.0 kompiliert</p>
<pre><code class="language-cpp">std::map&lt;int, A&gt; map;
        map[0] = std::move(a1);
        std::cout &lt;&lt; &quot;---&quot; &lt;&lt; std::endl;
        map.insert(std::map&lt;int, A&gt;::value_type(1, std::move(a2)));
</code></pre>
<p>zu</p>
<blockquote>
<p>move<br />
move<br />
move<br />
---<br />
move<br />
move</p>
</blockquote>
]]></description><link>https://www.c-plusplus.net/forum/post/2019478</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2019478</guid><dc:creator><![CDATA[XSpille]]></dc:creator><pubDate>Fri, 11 Feb 2011 08:29:28 GMT</pubDate></item><item><title><![CDATA[Reply to C++0x: Forcieren des Move-Konstruktors on Fri, 11 Feb 2011 09:08:22 GMT]]></title><description><![CDATA[<blockquote>
<p>move<br />
move<br />
move<br />
---<br />
move<br />
move</p>
</blockquote>
<p>Gibst Du eigentlich auch &quot;move&quot; bei einer Move-Zuweisung aus? Ich kann mir so oder so nicht ganz erklären, warum beim ersten Teil 3mal move auftaucht.</p>
<p>Übrigens soll es möglich sein, eine map auch so zu befüllen:</p>
<pre><code class="language-cpp">map.insert({1,std::move(a1)});
map.emplace(2,std::move(a2));
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2019489</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2019489</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Fri, 11 Feb 2011 09:08:22 GMT</pubDate></item><item><title><![CDATA[Reply to C++0x: Forcieren des Move-Konstruktors on Fri, 11 Feb 2011 11:41:35 GMT]]></title><description><![CDATA[<p>krümelkacker schrieb:</p>
<blockquote>
<blockquote>
<p>move<br />
move<br />
move<br />
---<br />
move<br />
move</p>
</blockquote>
<p>Gibst Du eigentlich auch &quot;move&quot; bei einer Move-Zuweisung aus? Ich kann mir so oder so nicht ganz erklären, warum beim ersten Teil 3mal move auftaucht.<br />
[/cpp]</p>
</blockquote>
<p>Nein... Ich habe genau den geposteten Code für Klasse A verwendet...</p>
<p>krümelkacker schrieb:</p>
<blockquote>
<p>Übrigens soll es möglich sein, eine map auch so zu befüllen:</p>
<pre><code class="language-cpp">map.insert({1,std::move(a1)});
map.emplace(2,std::move(a2));
</code></pre>
</blockquote>
<p>Danke für diese Anmerkung! <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="👍"
    /><br />
emplace kannte ich bisher nur von vector &amp; die andere Schreibweise<br />
hab ich höchstens mal hier im Forum gesehen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2019573</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2019573</guid><dc:creator><![CDATA[XSpille]]></dc:creator><pubDate>Fri, 11 Feb 2011 11:41:35 GMT</pubDate></item><item><title><![CDATA[Reply to C++0x: Forcieren des Move-Konstruktors on Fri, 11 Feb 2011 12:09:15 GMT]]></title><description><![CDATA[<pre><code>#include&lt;vector&gt; 
#include&lt;iostream&gt; 

class A { 
public: 
        A(){} 
        A(const A&amp;){ 
                std::cout &lt;&lt; &quot;copy&quot; &lt;&lt; std::endl; 
        } 
        A(A&amp;&amp; a){ 
                std::cout &lt;&lt; &quot;move&quot; &lt;&lt; std::endl; 
        } 

				~A() {
					std::cout &lt;&lt; &quot;~A&quot; &lt;&lt; std::endl;
				}
}; 

int main() 
{ 
        A a1;
        std::vector&lt;A&gt; vec;
        vec.push_back(std::move(a1)); // Hier wird der Move-Kontruktor aufgerufen 
        return 0; 
}
</code></pre>
<p>Was ich in diesem Fall nicht verstehe ist, warum der Destruktor 4 mal aufgerufen wird. Ich dachte, mit dem Move-Konstruktor wird das gleiche Objekt in den vector gepackt, daher sollte doch auch nur einmal der Destruktor für a1 ufgerufen werden?</p>
<blockquote>
<p>$ ./test<br />
move<br />
~A<br />
~A</p>
</blockquote>
]]></description><link>https://www.c-plusplus.net/forum/post/2019591</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2019591</guid><dc:creator><![CDATA[C++0X]]></dc:creator><pubDate>Fri, 11 Feb 2011 12:09:15 GMT</pubDate></item><item><title><![CDATA[Reply to C++0x: Forcieren des Move-Konstruktors on Fri, 11 Feb 2011 12:10:55 GMT]]></title><description><![CDATA[<p>Ich meine natürlich 2 mal - 4 mal im ersten Beispiel mit a1 und a2...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2019593</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2019593</guid><dc:creator><![CDATA[C++0X]]></dc:creator><pubDate>Fri, 11 Feb 2011 12:10:55 GMT</pubDate></item><item><title><![CDATA[Reply to C++0x: Forcieren des Move-Konstruktors on Fri, 11 Feb 2011 12:28:02 GMT]]></title><description><![CDATA[<p>C++0X schrieb:</p>
<blockquote>
<p>Was ich in diesem Fall nicht verstehe ist, warum der Destruktor 2 mal aufgerufen wird. Ich dachte, mit dem Move-Konstruktor wird das gleiche Objekt in den vector gepackt, daher sollte doch auch nur einmal der Destruktor für a1 ufgerufen werden?</p>
</blockquote>
<p>Es wird nicht das gleiche Objekt in den vector gepackt.<br />
Es wird ein neues Objekt erstellt, jedoch mit der Erlaubnis, die Inhalte des<br />
ursprünglichen Objekts zu zerstören. (Der Destruktor muss noch funktionieren)</p>
<p>So kann man sich beispielweise eine tiefe Kopie ersparen: (okay hier nur ein int* ^^)</p>
<pre><code class="language-cpp">class A { 
public: 
        A(A&amp;&amp; a){ 
                this-&gt;i = a.i;
                a.i = 0; // ansonsten funktioniert delete i; im Destruktor nicht mehr (doppel-delete)
        }
private:
        int* i;
}
</code></pre>
<p>So übernimmt man einfach Teile des Original-Objektes, da dieses sie nicht mehr braucht.</p>
<p>Gruß,<br />
XSpille</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2019604</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2019604</guid><dc:creator><![CDATA[XSpille]]></dc:creator><pubDate>Fri, 11 Feb 2011 12:28:02 GMT</pubDate></item><item><title><![CDATA[Reply to C++0x: Forcieren des Move-Konstruktors on Fri, 11 Feb 2011 12:35:07 GMT]]></title><description><![CDATA[<p>C++0X schrieb:</p>
<blockquote>
<p>Was ich in diesem Fall nicht verstehe ist, warum der Destruktor [2] mal aufgerufen wird. Ich dachte, mit dem Move-Konstruktor wird das gleiche Objekt in den vector gepackt, daher sollte doch auch nur einmal der Destruktor für a1 ufgerufen werden?</p>
</blockquote>
<p>Warum das denn? Du hast doch zwei A-Objekte, a1 und vec[0]. Es wird nur statt dem Kopierkonstruktor der Movekonstruktor aufgerufen, um vec[0] zu erzeugen. Was im Movekonstruktor passiert ist ganz allein Deine Sache. Darüber hinaus gibt es keine Magie.</p>
<p>Vielleicht hast Du duch aber auch von dem Namen der Hilfsfunktion &quot;move&quot; irritieren lassen. Innerhalb von move passiert nichts besonderes. Es ist hier nur eine Abkürzung für static_cast&lt;A&amp;&amp;&gt;(a1). Dieser Ausdruck bezieht sich immer noch auf a1, ist aber jetzt kein Lvalue-Ausdruck mehr sondern ein Rvalue-Ausdruck.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2019608</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2019608</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Fri, 11 Feb 2011 12:35:07 GMT</pubDate></item><item><title><![CDATA[Reply to C++0x: Forcieren des Move-Konstruktors on Fri, 11 Feb 2011 12:36:03 GMT]]></title><description><![CDATA[<p>[quote=&quot;XSpille&quot;]</p>
<p>C++0X schrieb:</p>
<blockquote>
<p>So übernimmt man einfach Teile des Original-Objektes, da dieses sie nicht mehr braucht.</p>
</blockquote>
<p>Ok, jetzt habe ich's verstanden. Dachte zuerst, der Move-Ausdruck würde bewirken, dass das eigentliche Objekt &quot;verschoben&quot; wird.</p>
<p>Vielen Dank für die Erklärung.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2019614</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2019614</guid><dc:creator><![CDATA[C++0X]]></dc:creator><pubDate>Fri, 11 Feb 2011 12:36:03 GMT</pubDate></item><item><title><![CDATA[Reply to C++0x: Forcieren des Move-Konstruktors on Sat, 12 Feb 2011 01:34:49 GMT]]></title><description><![CDATA[<p>doppelpost</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2019947</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2019947</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Sat, 12 Feb 2011 01:34:49 GMT</pubDate></item><item><title><![CDATA[Reply to C++0x: Forcieren des Move-Konstruktors on Sat, 12 Feb 2011 01:34:35 GMT]]></title><description><![CDATA[<p>In C++ können Objekte nicht in dem Sinn &quot;verschoben&quot; werden. Man kann nur ein neues Objekt erstellen, das dem alten Objekt seine Resourcen &quot;klaut&quot;. Bzw. eine Zuweisung machen die einem anderen Objekt seine Resourcen &quot;klaut&quot;. Das ist das was man im Zusammenhang mit C++ als &quot;Move Semantik&quot; bezeichnet.</p>
<p>Das &quot;andere&quot; Objekt, dem die Resourcen geklaut werden, wird dabei in einem beliebigen aber &quot;gültigen&quot; Zustand hinterlassen, in dem es zumindest noch zerstört werden kann. Und es muss auch zerstört werden, da es ja immer noch existiert.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2019946</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2019946</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Sat, 12 Feb 2011 01:34:35 GMT</pubDate></item></channel></rss>