<?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[Rückgabe von rValue-Referenzen in virtuellen Funktionen]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>also bisher hab ich rValue-Referenzen nur als Parameter verwendet.<br />
Irgendwer hier im Forum hat - wenn ich mich richtig erinnere - mal gesagt,<br />
dass man bei der Rückgabe von Objekten (normalerweise?) keine rValue-Referenzen<br />
zurückgeben braucht, weil der Compiler - wenn möglich - implizit durch<br />
den Move-Konstrukor statt des Copy-Konstruktors verwendet.</p>
<p>Wenn jetzt allerdings eine Funktion virtual ist, kann er das (glaube ich)<br />
nicht mehr erkennen. Deswegen möchte ich halt explizit eine<br />
rValue-Referenz zurückgeben.</p>
<p>Deswegen würde ich gerne wissen, ob das so zulässig ist:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;

class MoveObject{
public:
        MoveObject(){}
        MoveObject(MoveObject&amp;&amp; obj){
                std::cout &lt;&lt; &quot;move1&quot; &lt;&lt; std::endl;
        }

        MoveObject&amp; operator=(MoveObject&amp;&amp; obj){
                std::cout &lt;&lt; &quot;move2&quot; &lt;&lt; std::endl;
                return *this;
        }

        MoveObject(const MoveObject&amp; obj){
                std::cout &lt;&lt; &quot;copy1&quot; &lt;&lt; std::endl;
        }

        MoveObject&amp; operator=(const MoveObject&amp; obj){
                std::cout &lt;&lt; &quot;copy2&quot; &lt;&lt; std::endl;
                return *this;
        }

};

class A{
public:
        virtual MoveObject&amp;&amp; get(){
                return std::move(MoveObject());
        }
};

class B : public A{
public:
        virtual MoveObject&amp;&amp; get(){
                return std::move(obj);
        }
private:
        MoveObject obj;
};

void move_it(A&amp; t){
        MoveObject o = t.get();
}

int main(int argc, char** arg){
        std::cout &lt;&lt; &quot;A:&quot; &lt;&lt; std::endl;
        A a;
        move_it(a);
        std::cout &lt;&lt; &quot;B:&quot; &lt;&lt; std::endl;
        B b;
        move_it(b);
        return 0;
}
</code></pre>
<p>Also eigentlich bin ich davon überzeugt, allerdings würde ich gerne<br />
eine Bestätigung haben, bevor ich mir etwas falsch angewöhne.<br />
Auf den ersten Blick scheint es ja auch zu funktionieren <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>
<blockquote>
<p>A:<br />
move1<br />
B:<br />
move1</p>
</blockquote>
<p>(Ja, ich weiß, dass hier obj in B danach nicht mehr zu gebrauchen ist <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="🙂"
    /> )<br />
Ohne rValue-Referenz optimiert mein Compiler (scheinbar) die Kopie bei der Rückgabe<br />
von A komplett raus:</p>
<blockquote>
<p>A:<br />
B:<br />
copy1</p>
</blockquote>
<p>Ich gehe mal davon aus, dass er move_it dann inlined.</p>
<p>Also nochmal abschließend die eigentliche Frage.<br />
Ist das gültig:</p>
<pre><code class="language-cpp">virtual MoveObject&amp;&amp; get(){
                return std::move(/*myMoveObject*/);
        }
</code></pre>
<p>Gruß,<br />
XSpille</p>
<p>EDIT: return type von operator=() korrigiert...</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/282421/rückgabe-von-rvalue-referenzen-in-virtuellen-funktionen</link><generator>RSS for Node</generator><lastBuildDate>Fri, 21 Aug 2026 07:44:17 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/282421.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 20 Feb 2011 05:46:23 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Rückgabe von rValue-Referenzen in virtuellen Funktionen on Mon, 21 Feb 2011 23:47:46 GMT]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>also bisher hab ich rValue-Referenzen nur als Parameter verwendet.<br />
Irgendwer hier im Forum hat - wenn ich mich richtig erinnere - mal gesagt,<br />
dass man bei der Rückgabe von Objekten (normalerweise?) keine rValue-Referenzen<br />
zurückgeben braucht, weil der Compiler - wenn möglich - implizit durch<br />
den Move-Konstrukor statt des Copy-Konstruktors verwendet.</p>
<p>Wenn jetzt allerdings eine Funktion virtual ist, kann er das (glaube ich)<br />
nicht mehr erkennen. Deswegen möchte ich halt explizit eine<br />
rValue-Referenz zurückgeben.</p>
<p>Deswegen würde ich gerne wissen, ob das so zulässig ist:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;

class MoveObject{
public:
        MoveObject(){}
        MoveObject(MoveObject&amp;&amp; obj){
                std::cout &lt;&lt; &quot;move1&quot; &lt;&lt; std::endl;
        }

        MoveObject&amp; operator=(MoveObject&amp;&amp; obj){
                std::cout &lt;&lt; &quot;move2&quot; &lt;&lt; std::endl;
                return *this;
        }

        MoveObject(const MoveObject&amp; obj){
                std::cout &lt;&lt; &quot;copy1&quot; &lt;&lt; std::endl;
        }

        MoveObject&amp; operator=(const MoveObject&amp; obj){
                std::cout &lt;&lt; &quot;copy2&quot; &lt;&lt; std::endl;
                return *this;
        }

};

class A{
public:
        virtual MoveObject&amp;&amp; get(){
                return std::move(MoveObject());
        }
};

class B : public A{
public:
        virtual MoveObject&amp;&amp; get(){
                return std::move(obj);
        }
private:
        MoveObject obj;
};

void move_it(A&amp; t){
        MoveObject o = t.get();
}

int main(int argc, char** arg){
        std::cout &lt;&lt; &quot;A:&quot; &lt;&lt; std::endl;
        A a;
        move_it(a);
        std::cout &lt;&lt; &quot;B:&quot; &lt;&lt; std::endl;
        B b;
        move_it(b);
        return 0;
}
</code></pre>
<p>Also eigentlich bin ich davon überzeugt, allerdings würde ich gerne<br />
eine Bestätigung haben, bevor ich mir etwas falsch angewöhne.<br />
Auf den ersten Blick scheint es ja auch zu funktionieren <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>
<blockquote>
<p>A:<br />
move1<br />
B:<br />
move1</p>
</blockquote>
<p>(Ja, ich weiß, dass hier obj in B danach nicht mehr zu gebrauchen ist <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="🙂"
    /> )<br />
Ohne rValue-Referenz optimiert mein Compiler (scheinbar) die Kopie bei der Rückgabe<br />
von A komplett raus:</p>
<blockquote>
<p>A:<br />
B:<br />
copy1</p>
</blockquote>
<p>Ich gehe mal davon aus, dass er move_it dann inlined.</p>
<p>Also nochmal abschließend die eigentliche Frage.<br />
Ist das gültig:</p>
<pre><code class="language-cpp">virtual MoveObject&amp;&amp; get(){
                return std::move(/*myMoveObject*/);
        }
</code></pre>
<p>Gruß,<br />
XSpille</p>
<p>EDIT: return type von operator=() korrigiert...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2023509</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2023509</guid><dc:creator><![CDATA[XSpille]]></dc:creator><pubDate>Mon, 21 Feb 2011 23:47:46 GMT</pubDate></item><item><title><![CDATA[Reply to Rückgabe von rValue-Referenzen in virtuellen Funktionen on Sun, 20 Feb 2011 07:14:07 GMT]]></title><description><![CDATA[<p>Rvalue-Referenzen sind REFERENZEN. Punkt. Ich kann mir beim besten Willen nicht erklären, warum so viele, die sich mit Rvalue-Referenzen beschäftigen, auf einmal Funktionen schreiben wollen, die Referenzen auf funktionslokale Objekte zurückgeben, die dann ungültig sind...</p>
<pre><code class="language-cpp">virtual MoveObject&amp;&amp; get(){
    return std::move(MoveObject());
  }
</code></pre>
<p><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f44e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--thumbs_down"
      title=":-1:"
      alt="👎"
    /> (dangling reference)</p>
<pre><code class="language-cpp">virtual MoveObject get(){
    return MoveObject();
  }
</code></pre>
<p><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>
<p>Wenn Du Dir unsicher bzgl Rvalue-Referenzen bist, dann bescgränke Dich darauf, sie nur für Move-Konstruktoren und Move-Zuweisungsoperatoren zu benutzten. Spar Dir auch unnötige std::move-Aufrufe. Wenn Du irgendwo ein std::move benutzt, wo es eigentlich nicht nötig ist, dann verhinderst Du damit copy/move-elision Optimierungen. Eine copy/move elision ist natürlich viel besser als eine move-konstruktion.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2023515</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2023515</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Sun, 20 Feb 2011 07:14:07 GMT</pubDate></item><item><title><![CDATA[Reply to Rückgabe von rValue-Referenzen in virtuellen Funktionen on Sun, 20 Feb 2011 08:56:04 GMT]]></title><description><![CDATA[<p>Gut, dass ich nachgefragt habe <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f62e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_open_mouth"
      title=":open_mouth:"
      alt="😮"
    /></p>
<p>krümelkacker schrieb:</p>
<blockquote>
<p>Rvalue-Referenzen sind REFERENZEN. Punkt. Ich kann mir beim besten Willen nicht erklären, warum so viele, die sich mit Rvalue-Referenzen beschäftigen, auf einmal Funktionen schreiben wollen, die Referenzen auf funktionslokale Objekte zurückgeben, die dann ungültig sind...</p>
</blockquote>
<p>So hab ich es noch gar nicht gesehen...</p>
<p>Ehrlich gesagt war das &amp;&amp; laut meiner (naiven) Annahme einfach nur die Erlaubnis<br />
den Rückgabewert/Parameter zu 'zerstören'.</p>
<p>Immerhin gibt man ja auch ein MoveObject zurück, das auf dem Stack liegt.<br />
Jetzt hätte man halt zusätzlich die Erlaubnis dieses zu manipulieren.<br />
So war jedenfalls mein Gedanke.</p>
<p>Also theoretisch sollte das in der compilertechnischen Umsetzung doch<br />
eigentlich keinen nennenswerten Unterschied machen.</p>
<p>Aber jetzt bin ich ja schlauer <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>Danke 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/2023544</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2023544</guid><dc:creator><![CDATA[XSpille]]></dc:creator><pubDate>Sun, 20 Feb 2011 08:56:04 GMT</pubDate></item><item><title><![CDATA[Reply to Rückgabe von rValue-Referenzen in virtuellen Funktionen on Sun, 20 Feb 2011 12:37:06 GMT]]></title><description><![CDATA[<p>krümelkacker schrieb:</p>
<blockquote>
<p>Rvalue-Referenzen sind REFERENZEN. Punkt. Ich kann mir beim besten Willen nicht erklären, warum so viele, die sich mit Rvalue-Referenzen beschäftigen, auf einmal Funktionen schreiben wollen, die Referenzen auf funktionslokale Objekte zurückgeben, die dann ungültig sind...</p>
</blockquote>
<p>Ich denke, das hängt damit zusammen, dass bisherige bekannte Konstrukte plötzlich eine neue Bedeutung bekommen. Bisher war klar, dass</p>
<pre><code class="language-cpp">MyClass Get();
</code></pre>
<p>eine Kopie erzeugt, im besten Fall noch mit (N)RVO wegoptimiert. Dass nun der gleiche Ausdruck ein implizites Move verursachen kann, wenn entsprechende Move-Konstruktoren definiert sind oder compilergeneriert werden, ist halt erst mal neu. Und da Move-Semantik zunächst immer mit RValue-Referenzen in Verbindung gebracht wird, scheint es naheliegend, dass man einen Move mit</p>
<pre><code class="language-cpp">MyClass&amp;&amp; Get();
</code></pre>
<p>kennzeichnet.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2023640</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2023640</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Sun, 20 Feb 2011 12:37:06 GMT</pubDate></item><item><title><![CDATA[Reply to Rückgabe von rValue-Referenzen in virtuellen Funktionen on Sun, 20 Feb 2011 14:14:49 GMT]]></title><description><![CDATA[<p>Außerdem gibt operator = einen Class&amp; zurück.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2023709</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2023709</guid><dc:creator><![CDATA[314159265358979]]></dc:creator><pubDate>Sun, 20 Feb 2011 14:14:49 GMT</pubDate></item><item><title><![CDATA[Reply to Rückgabe von rValue-Referenzen in virtuellen Funktionen on Mon, 21 Feb 2011 07:55:20 GMT]]></title><description><![CDATA[<p>314159265358979 schrieb:</p>
<blockquote>
<p>Außerdem gibt operator = einen Class&amp; zurück.</p>
</blockquote>
<p>Was ist das jetzt für eine Weisheit? <code>MoveObject::operator=(const MoveObject&amp;)</code> gibt goarnix zurück. Der Operator <em>sollte</em> <code>MoveObject&amp;</code> zurückgeben, wenn man das Schreiben von <code>MoveObject a = b = c;</code> erlauben möchte.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2024029</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2024029</guid><dc:creator><![CDATA[brotbernd]]></dc:creator><pubDate>Mon, 21 Feb 2011 07:55:20 GMT</pubDate></item><item><title><![CDATA[Reply to Rückgabe von rValue-Referenzen in virtuellen Funktionen on Mon, 21 Feb 2011 14:10:49 GMT]]></title><description><![CDATA[<p>brotbernd schrieb:</p>
<blockquote>
<p>Was ist das jetzt für eine Weisheit?</p>
</blockquote>
<p>Es ist mehr eine Konvention.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2024179</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2024179</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Mon, 21 Feb 2011 14:10:49 GMT</pubDate></item><item><title><![CDATA[Reply to Rückgabe von rValue-Referenzen in virtuellen Funktionen on Mon, 21 Feb 2011 14:39:47 GMT]]></title><description><![CDATA[<p>Wichtiger ist eigentlich, dass operator=, wenn man sich nicht sehr dämlich anstellt, keine Referenz auf ein funktionslokales Objekt zurückgibt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2024198</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2024198</guid><dc:creator><![CDATA[seldon]]></dc:creator><pubDate>Mon, 21 Feb 2011 14:39:47 GMT</pubDate></item><item><title><![CDATA[Reply to Rückgabe von rValue-Referenzen in virtuellen Funktionen on Mon, 21 Feb 2011 14:48:14 GMT]]></title><description><![CDATA[<p>Das stimmt natürlich. Ich merke gerade, dass ich wahrscheinlich den Post von Pi falsch interpretiert habe...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2024205</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2024205</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Mon, 21 Feb 2011 14:48:14 GMT</pubDate></item><item><title><![CDATA[Reply to Rückgabe von rValue-Referenzen in virtuellen Funktionen on Mon, 21 Feb 2011 14:52:01 GMT]]></title><description><![CDATA[<p>Um das mal etwas zu verdeutlichen, was hier geschrieben wurde: man kann nicht jedes Objekt &quot;moven&quot; bzw. nicht jede Klasse movable machen. Das hat nur Sinn, wenn eine Klasse Ressourcen belegt, die sie problemlos weiterschieben kann. Beispielsweise std::vector: Eine mögliche implementierung von vector hat intern<br />
- ein size_t für die Anzahl der belegten Elemente (size())<br />
- ein size_t für die Größe des Allokierten Speichers (capacity())<br />
- einen Allokator<br />
- eine Pointer auf den Speicherbereich, der dem vector gehört</p>
<p>Der alte copy-Ctor musste folgende Schritte machen:<br />
- Allokator kopieren<br />
<strong>- neuen Speicher belegen (teuer!)</strong><br />
- Pointer auf den neuen Speicher setzen<br />
- capacity entsprechend setzen<br />
<strong>- alle Elemente rüberkopieren (möglicherweise auch teuer)</strong><br />
- size koperen</p>
<p>Der neue Move-ctor muss dagegen nur folgende Schritte machen:<br />
- Allokator kopieren<br />
<strong>- Pointer kopieren und Pointer des Originals auf 0 setzen</strong><br />
- capacity kopieren<br />
- size kopieren</p>
<p>Daraus erkennt man, dass das Kopieren nicht komplett wegfällt (anders als einige wohl erwarten würden), es fällt nur der größte Teil weg.</p>
<p>Nehmen wir folgende Funktion und einen Aufruf:</p>
<pre><code class="language-cpp">vector f()
{
  vector vec; //(1)
  //...
  return vec; //(2)
}

//...
vector myvec = f(); //(3)
</code></pre>
<p>mit der alten copy-Semantik passiert folgendes:<br />
an Stelle (1) wird ein vector konstruiert<br />
an Stelle (2) wird ein neuer (temporärer) vector aus vec copy-konstruiert<br />
an Stelle (3) wird myvec aus dem temporären Objekt copy-konstruiert</p>
<p>durch NRVO kann die Kopie an Stelle (2) wegoptimiert werden (meist nur im Releasemodus). vec wird dann quasi &quot;außerhalb&quot; der Funktion erstellt und darauf operiert, so dass er beim Verlassen der Funktion nicht erst herauskopiert werden muss. Es bleiben noch (1) und (3)</p>
<p>durch einen move-konstruktor in C++0x bindet das temporäre Objekt, das von f() zurückgegeben wird, an Stelle (3) an die RRef des move-ctor (weil temporäre Objekte eben rValues sind und deshalb an RRefs binden <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/26a0.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--warning"
      title=":warning:"
      alt="⚠"
    />). Außerdem weiß der Compiler, dass vec nach dem return zerstört wird und kann es in einen rvalue konvertieren, so dass er an Stelle (2) das temporäre Objekt aus vec move-konsturieren kann. Das allerdings nur, wenn NRVO nicht zieht und vec von vornherein außerhalb der Funktion konstruiert wird.</p>
<p>An der Stelle mit dem <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/26a0.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--warning"
      title=":warning:"
      alt="⚠"
    /> ist der Knackpunkt (und der Denkfehler, den der OP begangen hat): Du musst keine RRef zurückgeben, um move-Semantik zu ermöglichen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2024213</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2024213</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Mon, 21 Feb 2011 14:52:01 GMT</pubDate></item><item><title><![CDATA[Reply to Rückgabe von rValue-Referenzen in virtuellen Funktionen on Mon, 21 Feb 2011 15:49:36 GMT]]></title><description><![CDATA[<p>Hi,</p>
<p>Kann man jetzt also sagen, dass C++0x das Problem sämtlicher dicker &quot;Moves&quot; löst? Ich habe ja oft Folgendes:</p>
<pre><code class="language-cpp">ComplexObject createComplexObject()
{
ComplexObject z;
z.loadX(&quot;bla.txt&quot;);
z.loadY(&quot;blub.txt&quot;);
z.loadZ(&quot;balu.txt&quot;);
return z;
}

ComplexObject t = createComplexObject();
</code></pre>
<p>wenn die Ladeoperation zeitkritisch ist, ist es schade, wenn hier alles kopiert wird. Der größte Aufwand wird hier dann aber beseitigt, sodass das nix schadet?</p>
<p>Weiterführender Gedanke: Das ist jetzt super-spekulativ, dafür entschuldige ich mich im Voraus. Aber map braucht ja als value etwas copyables. Dürfte sich das durch die Move-Semantik nicht auch erübrigen, sodass es nur movable sein muss?</p>
<p>Ich muss mich da unbedingt Mal besser einlesen...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2024263</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2024263</guid><dc:creator><![CDATA[Eisflamme]]></dc:creator><pubDate>Mon, 21 Feb 2011 15:49:36 GMT</pubDate></item><item><title><![CDATA[Reply to Rückgabe von rValue-Referenzen in virtuellen Funktionen on Mon, 21 Feb 2011 15:59:05 GMT]]></title><description><![CDATA[<p>Eisflamme schrieb:</p>
<blockquote>
<p>Kann man jetzt also sagen, dass C++0x das Problem sämtlicher dicker &quot;Moves&quot; löst?</p>
</blockquote>
<p>Nicht sämtliche, aber viele. Die Klassen müssen movable sein. Und dann gibt es Fälle, die sich für Ressourcenklau nur bedingt eignen (z.B. statische Arrays).</p>
<p>Eisflamme schrieb:</p>
<blockquote>
<p>Dürfte sich das durch die Move-Semantik nicht auch erübrigen, sodass es nur movable sein muss?</p>
</blockquote>
<p>STL-Container werden movable, non-copyable Typen unterstützen. Allerdings ist mir nicht ganz klar, wie das Zusammenspiel mit kopierenden STL-Algorithmen konkret aussieht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2024267</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2024267</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Mon, 21 Feb 2011 15:59:05 GMT</pubDate></item><item><title><![CDATA[Reply to Rückgabe von rValue-Referenzen in virtuellen Funktionen on Mon, 21 Feb 2011 16:07:42 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Allerdings ist mir nicht ganz klar, wie das Zusammenspiel mit kopierenden STL-Algorithmen konkret aussieht.</p>
</blockquote>
<p>Kopierende Algorithmen werden natürlich copyable Elemente benötigen. Nur werden viele Algorithmen eben zu movenden Algorithmen <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="😉"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2024271</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2024271</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Mon, 21 Feb 2011 16:07:42 GMT</pubDate></item><item><title><![CDATA[Reply to Rückgabe von rValue-Referenzen in virtuellen Funktionen on Mon, 21 Feb 2011 18:10:43 GMT]]></title><description><![CDATA[<p>Okay, alles klar. <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="🙂"
    /> MSVC unterstützt moveable Container noch nicht, richtig? Sind die Move-Container schon im aktuellen Draft? Ich schätze, ja.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2024347</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2024347</guid><dc:creator><![CDATA[Eisflamme]]></dc:creator><pubDate>Mon, 21 Feb 2011 18:10:43 GMT</pubDate></item><item><title><![CDATA[Reply to Rückgabe von rValue-Referenzen in virtuellen Funktionen on Mon, 21 Feb 2011 19:09:27 GMT]]></title><description><![CDATA[<p>Eisflamme schrieb:</p>
<blockquote>
<p>MSVC unterstützt moveable Container noch nicht, richtig?</p>
</blockquote>
<p>Doch, die 2010er Version schon. Ich weiss allerdings nicht, wie weit die Unterstützung reicht, da ich bisher noch nicht gross von den neuen Features Gebrauch gemacht habe.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2024378</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2024378</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Mon, 21 Feb 2011 19:09:27 GMT</pubDate></item><item><title><![CDATA[Reply to Rückgabe von rValue-Referenzen in virtuellen Funktionen on Mon, 21 Feb 2011 19:46:52 GMT]]></title><description><![CDATA[<p>Eisflamme schrieb:</p>
<blockquote>
<p>Okay, alles klar. <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="🙂"
    /> MSVC unterstützt moveable Container noch nicht, richtig?</p>
</blockquote>
<p>Äh, doch, schon. Die Container in der Stadnard-Library von Visual Studio 2010 unterstützen moveable Elemente und sind auch selbst movable.</p>
<p>Das einzige was noch nicht unterstützt wird sind die automatisch generierten Move-Konstruktoren und Move-Assigmnent-Operatoren.<br />
Wenn du also Klassen hast die Container als Member haben, und willst dass diese Klassen von Move-Semantik profitieren, dann musst du selbst nen Move-Konstruktor und nen Move-Assignment-Operator definieren. (Im aktuellen Standard-Draft ist vorgesehen dass unter bestimmten Voraussetzungen automatisch welche generiert werden, aber das kann Visual Studio 2010 eben noch nicht)</p>
<p>BTW: <code>std::map&lt;Foo, MoveOnlyType&gt;</code> funktioniert mit Visual Studio 2010 problemlos.</p>
<blockquote>
<p>Sind die Move-Container schon im aktuellen Draft? Ich schätze, ja.</p>
</blockquote>
<p>Was für Move-Container? Die bestehenden Container vector, list, map, set etc. werden - dort wo es Sinn macht - angepasst, damit sie Moves für bessere Performance ausnutzen können. Bzw. damit man sie mit &quot;move only&quot; Typen verwenden kann, wo vorher kopierbare Typen nötig waren. Diese Anpassungen sind soweit ich weiss auch im aktuellen Draft schon enthalten - würde mich SEHR wundern wenn nicht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2024395</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2024395</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Mon, 21 Feb 2011 19:46:52 GMT</pubDate></item><item><title><![CDATA[Reply to Rückgabe von rValue-Referenzen in virtuellen Funktionen on Mon, 21 Feb 2011 21:53:45 GMT]]></title><description><![CDATA[<blockquote>
<p>Was für Move-Container? Die bestehenden Container vector, list, map, set etc. werden - dort wo es Sinn macht - angepasst, damit sie Moves für bessere Performance ausnutzen können</p>
</blockquote>
<p>Das meinte ich - danke, das beantwortet alle meine Fragen. <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="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2024460</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2024460</guid><dc:creator><![CDATA[Eisflamme]]></dc:creator><pubDate>Mon, 21 Feb 2011 21:53:45 GMT</pubDate></item><item><title><![CDATA[Reply to Rückgabe von rValue-Referenzen in virtuellen Funktionen on Tue, 22 Feb 2011 00:05:31 GMT]]></title><description><![CDATA[<p>Ich werde dann wohl zukünftig, wenn es wirklich performance-technisch notwendig<br />
ist, auf Heap-Objekte in einem unique_ptr zurückgreifen:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;memory&gt;

class MoveObject{};

class A{
public:
        virtual std::unique_ptr&lt;MoveObject&gt; get(){
                return std::unique_ptr&lt;MoveObject&gt;(new MoveObject());
        }
};

class B : public A{
public:
        B() : obj(new MoveObject()){
        }

        virtual std::unique_ptr&lt;MoveObject&gt; get(){
                return std::move(obj);
        }
private:
        std::unique_ptr&lt;MoveObject&gt; obj;
};

void move_it(A&amp; t){
        std::unique_ptr&lt;MoveObject&gt; o(t.get());
}

int main(int argc, char** arg){
        A a;
        move_it(a);
        B b;
        move_it(b);
        return 0;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2024497</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2024497</guid><dc:creator><![CDATA[XSpille]]></dc:creator><pubDate>Tue, 22 Feb 2011 00:05:31 GMT</pubDate></item><item><title><![CDATA[Reply to Rückgabe von rValue-Referenzen in virtuellen Funktionen on Tue, 22 Feb 2011 00:11:41 GMT]]></title><description><![CDATA[<p>XSpille schrieb:</p>
<blockquote>
<p>Ich werde dann wohl zukünftig, wenn es wirklich performance-technisch notwendig<br />
ist, auf Heap-Objekte in einem unique_ptr zurückgreifen:</p>
</blockquote>
<p>Wenn <code>MoveObject</code> movable ist, bringt das aber nichts. Durch die dynamische Allokation auf dem Freestore kann das Programm sogar langsamer werden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2024500</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2024500</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Tue, 22 Feb 2011 00:11:41 GMT</pubDate></item><item><title><![CDATA[Reply to Rückgabe von rValue-Referenzen in virtuellen Funktionen on Tue, 22 Feb 2011 00:56:58 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>XSpille schrieb:</p>
<blockquote>
<p>Ich werde dann wohl zukünftig, wenn es wirklich performance-technisch notwendig<br />
ist, auf Heap-Objekte in einem unique_ptr zurückgreifen:</p>
</blockquote>
<p>Wenn <code>MoveObject</code> movable ist, bringt das aber nichts. Durch die dynamische Allokation auf dem Freestore kann das Programm sogar langsamer werden.</p>
</blockquote>
<p>Aber sobald eine Funktion virtual ist, kann der Kompiler (meiner Meinung nach)<br />
keine Aussage mehr darüber treffen, ob er das Objekt moven kann oder kopieren<br />
muss...<br />
EDIT: Zumindest, wenn es movebar und kopierbar ist.</p>
<p>Sehe ich das falsch? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /><br />
Natürlich werde ich es nicht bei 'kleinen' Objekten verwenden.<br />
Über den Overhead einer dynamischen Allokation bin ich mir bewußt....</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2024507</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2024507</guid><dc:creator><![CDATA[XSpille]]></dc:creator><pubDate>Tue, 22 Feb 2011 00:56:58 GMT</pubDate></item><item><title><![CDATA[Reply to Rückgabe von rValue-Referenzen in virtuellen Funktionen on Tue, 22 Feb 2011 07:22:46 GMT]]></title><description><![CDATA[<p>XSpille schrieb:</p>
<blockquote>
<p>Aber sobald eine Funktion virtual ist, kann der Kompiler (meiner Meinung nach)<br />
keine Aussage mehr darüber treffen, ob er das Objekt moven kann oder kopieren<br />
muss...</p>
</blockquote>
<p>Das hat nichts mit virtuellen Funktionen zu tun. Ob man Objekte &quot;moven&quot; kann, hängt nur von der Klassendefinition ab, also, ob die Klasse Move-Ctor und Move-Assignment anbietet oder nicht.</p>
<p>XSpille schrieb:</p>
<blockquote>
<p>Sehe ich das falsch? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /></p>
</blockquote>
<p>Ja.</p>
<p>unique_ptr&lt;&gt; kann man auch nicht kopieren un trotzdem kannst Du das Ding von einer virtuellen Funktion zurückgeben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2024537</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2024537</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Tue, 22 Feb 2011 07:22:46 GMT</pubDate></item><item><title><![CDATA[Reply to Rückgabe von rValue-Referenzen in virtuellen Funktionen on Tue, 22 Feb 2011 10:02:56 GMT]]></title><description><![CDATA[<p>XSpille schrieb:</p>
<blockquote>
<p>Aber sobald eine Funktion virtual ist, kann der Kompiler (meiner Meinung nach)<br />
keine Aussage mehr darüber treffen, ob er das Objekt moven kann oder kopieren<br />
muss...<br />
EDIT: Zumindest, wenn es movebar und kopierbar ist.</p>
</blockquote>
<p>Müsste IMO egal sein.<br />
Wichtig ist nur, dass der Return-Typ vollständig bekannt ist, und das ist er ja. Einerseits dort wo die Funktion definiert wird, und andrerseits auch dort wo sie aufgerufen wird.</p>
<p>Selbst mit Covariant-Returns kann man keinen Fall konstruieren der nicht ohne Covariant-Returns und ohne virtual functions auch möglich wäre.</p>
<p>Warum meinst du dass es einen Unterschied machen würde?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2024602</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2024602</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 22 Feb 2011 10:02:56 GMT</pubDate></item><item><title><![CDATA[Reply to Rückgabe von rValue-Referenzen in virtuellen Funktionen on Tue, 22 Feb 2011 10:53:38 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>Warum meinst du dass es einen Unterschied machen würde?</p>
</blockquote>
<p>Sorry an alle, die ich verwirrt habe <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /></p>
<p>Knoten im Kopf... <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f576.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--sunglasses"
      title=":sunglasses:"
      alt="🕶"
    /></p>
<p>Wer nicht weiter verwirrt werden möchte überspringt den Rest <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>Ich hatte mir eingebildet, dass bei dem Copy- bzw. Move-Konstruktor<br />
in beiden Fällen, das Original-Objekt ankommt. Im zweiten Fall wird ja,<br />
wie man auch an der Ausgabe, sieht eine Kopie vor der Rückgabe erstellt. Im Move-Konstruktor<br />
würde (wenn es so wäre) die Member-Variable dann unbrauchbar gemacht, im Copy-Constructor nicht.<br />
(Ich hab mir quasi eingebildet, man gibt ne Referenz zurück, was natürlich<br />
im ersten Fall nicht geht und man ja auch anders in der Signatur angeben kann)<br />
Naja... etwas verwirrt halt <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f44e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--thumbs_down"
      title=":-1:"
      alt="👎"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2024629</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2024629</guid><dc:creator><![CDATA[XSpille]]></dc:creator><pubDate>Tue, 22 Feb 2011 10:53:38 GMT</pubDate></item><item><title><![CDATA[Reply to Rückgabe von rValue-Referenzen in virtuellen Funktionen on Tue, 22 Feb 2011 12:47:13 GMT]]></title><description><![CDATA[<p>XSpille schrieb:</p>
<blockquote>
<p>Ich hatte mir eingebildet, dass bei dem Copy- bzw. Move-Konstruktor in beiden Fällen, das Original-Objekt ankommt.</p>
</blockquote>
<p>Nein.</p>
<p>Kleine Analogie (die wie alle Analogien ihre Grenzen hat):<br />
Siehs wie einen Eimer mit gefärbtem Wasser. Der Eimer ist das Objekt, das Wasser sind die Ressourcen - wenn du nur einen tropfenden kleinen Wasserhahn hast sinds teuere Ressourcen.<br />
Ein Copy-Ctor würde den Eimer kopieren (neuen Eimer aus dem Schrank holen kostet nicht viel), den dann mit frischem Wasser volltröpfeln (das kostet Zeit!) und das dann genauso färben wie das Original. Der Originaleimer wird weggeworfen, vorher wird dessen gefärbtes Wasser weggekippt (d.h. die Ressourcen wieder freigegeben).</p>
<p>Ein Move-Ctor kopiert auch Eimer (nimmt also NICHT das Original, neuer Eimer kostet aber ja nicht viel) und kippt das Wasser aus dem alten Eimer in den neuen Eimer. Das darf er, weil der Originaleimer ein rValue ist, d.h. weil der eh gleich weggeworfen wird.</p>
<p>rValue-Referenzen sind also Referenzen, die extra für Wegwerfeimer gedacht sind <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="😉"
    /></p>
<p>Nochmal der Klarheit halber: Es kommt nicht das Originalobjekt an - du hast ein neues Objekt, allerdings <em>mit der selben Ressource</em> wie im alten Objekt.</p>
<p>XSpille schrieb:</p>
<blockquote>
<p>Im Move-Konstruktor würde (wenn es so wäre) die Member-Variable dann unbrauchbar gemacht, im Copy-Constructor nicht.</p>
</blockquote>
<p>Im Grunde stimmt das. Nur geht es beim Moven nicht um x-beliebige Membervariablen sondern um Ressourcen, z.B. allokierten Speicher, Dateihandles, Verbindungen etc. (Ressourcenlose Dinge wie ints kann man nicht moven)<br />
Im Move-Ctor wird die Ressource des Originalobjektes an das neue Objekt übergeben. Alles weitere (z.B. zusätzliche Daten, wie size und capacity beim vector-Beispiel oben) wird kopiert bzw. semantisch korrekt neu initialisiert.<br />
Eine Nebenwirkung der ganzen Move-Geschichte ist, dass Destruktoren von movable Klassen den Fall berücksichtigen müssen, dass die Klasse die Ressource nicht mehr besitzt (Eimer leer), weil eben der Fall auftreten kann, dass sie per move-Ctor (oder move-Assignment) bereits an ein anderes Objekt der Klasse übergeben worden ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2024679</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2024679</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Tue, 22 Feb 2011 12:47:13 GMT</pubDate></item><item><title><![CDATA[Reply to Rückgabe von rValue-Referenzen in virtuellen Funktionen on Tue, 22 Feb 2011 13:21:24 GMT]]></title><description><![CDATA[<p>Noch ein Zusatz. Das &quot;Umkippen der Eimerinhalte&quot; ist Sache des Klassendesigners. Wie/Was da genau passiert, wird im Move-Ctor definiert. Da steckt keine besondere Compiler-Magie hinter.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2024700</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2024700</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Tue, 22 Feb 2011 13:21:24 GMT</pubDate></item><item><title><![CDATA[Reply to Rückgabe von rValue-Referenzen in virtuellen Funktionen on Tue, 22 Feb 2011 17:25:31 GMT]]></title><description><![CDATA[<p>Lohnt es sich eigentlich, bei der Implementierung des Move-Konstruktors auf ein <code>swap()</code> zurückzugreifen, falls vorhanden? Man hätte möglicherweise ein paar unnötige Operationen, aber dafür ist die Implementierung einfach, semantisch korrekt und verwendet Code wieder.</p>
<p>Also eine Art Idiom &quot;Move-and-Swap&quot;?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2024881</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2024881</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Tue, 22 Feb 2011 17:25:31 GMT</pubDate></item></channel></rss>