<?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[Referenz auf Klassenattribut zurückliefern]]></title><description><![CDATA[<p>Ich hab folgende Methode</p>
<pre><code class="language-cpp">vector&lt;T&gt;&amp; Access()
	{
		return data;
	}
</code></pre>
<p>Eigentlich will ich nur, dass man in jedem Fall eine Referenz zurückbekommt. So wie das jetzt ist, kann man sich das scheinbar aussuchen ob man eine Kopie oder eine Referenz will:</p>
<pre><code class="language-cpp">vector&lt;MeinT&gt; vec = klasse.Access();  // Lokale Kopie
vector&lt;MeinT&gt; &amp;vec = klasse.Access();  // Referenz
</code></pre>
<p>Ist das richtig so, ich finde das gerade sehr merkwürdig?!?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/250275/referenz-auf-klassenattribut-zurückliefern</link><generator>RSS for Node</generator><lastBuildDate>Wed, 16 Sep 2026 03:12:20 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/250275.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 16 Sep 2009 07:22:26 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Referenz auf Klassenattribut zurückliefern on Wed, 16 Sep 2009 07:22:26 GMT]]></title><description><![CDATA[<p>Ich hab folgende Methode</p>
<pre><code class="language-cpp">vector&lt;T&gt;&amp; Access()
	{
		return data;
	}
</code></pre>
<p>Eigentlich will ich nur, dass man in jedem Fall eine Referenz zurückbekommt. So wie das jetzt ist, kann man sich das scheinbar aussuchen ob man eine Kopie oder eine Referenz will:</p>
<pre><code class="language-cpp">vector&lt;MeinT&gt; vec = klasse.Access();  // Lokale Kopie
vector&lt;MeinT&gt; &amp;vec = klasse.Access();  // Referenz
</code></pre>
<p>Ist das richtig so, ich finde das gerade sehr merkwürdig?!?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1779580</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1779580</guid><dc:creator><![CDATA[AllesWeg]]></dc:creator><pubDate>Wed, 16 Sep 2009 07:22:26 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz auf Klassenattribut zurückliefern on Wed, 16 Sep 2009 07:29:15 GMT]]></title><description><![CDATA[<p>Ist so, kannst nix dran ändern. Aber es ist doch schön, wenn der Benutzer deiner Klasse es sich aussuchen kann, ob er nicht lieber mit ner Kopie statt ner Referenz arbeitet... Vllt. braucht er ja ne Kopie.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1779587</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1779587</guid><dc:creator><![CDATA[Kopist]]></dc:creator><pubDate>Wed, 16 Sep 2009 07:29:15 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz auf Klassenattribut zurückliefern on Wed, 16 Sep 2009 08:25:25 GMT]]></title><description><![CDATA[<p>Man sollte niemals Membervariablen als Referenz zurück geben. Siehe Scott Meyers &quot;Effektiv C++ Programmieren&quot;. Da dieses Vorgehen die Kapselung ad absurdum führt! Kannste gleich das Member als public deklarieren, wenn du das machst. Members gibt man nur in äußersten bestimmten Fällen als Ref zurück, z.B. wenn es sich bei der Klasse um einen Container handelt.</p>
<p>Übrigens, jeder gute Compiler kann Kopien von Objekten weg optimieren! Also, keine Referenz zurück geben!</p>
<p>Und lokale Variablen, gibt man auch nicht als Referenz zurück. Dürfte auch jeder vernünftige Compiler eine Warning ausspucken.</p>
<p>Einfach mal im Netz oder hier im Forum nach RVO suchen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1779619</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1779619</guid><dc:creator><![CDATA[Artchi]]></dc:creator><pubDate>Wed, 16 Sep 2009 08:25:25 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz auf Klassenattribut zurückliefern on Wed, 16 Sep 2009 12:50:25 GMT]]></title><description><![CDATA[<p>Artchi schrieb:</p>
<blockquote>
<p>Man sollte niemals Membervariablen als Referenz zurück geben.</p>
</blockquote>
<p>Das würde ich nicht auf Const-Referenzen verallgemeinern (ich bin mir nicht sicher, ob du dich nur auf Referenzen auf unqualifizierte Objekte bezogen hast).</p>
<p>Auch mit der Optimierung ist das nicht immer so einfach. Die Chancen auf RVO stehen gut, wenn es sich um funktions-lokale Variablen handelt - bei Membervariablen hingegen weniger.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1779771</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1779771</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Wed, 16 Sep 2009 12:50:25 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz auf Klassenattribut zurückliefern on Wed, 16 Sep 2009 17:48:52 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Artchi schrieb:</p>
<blockquote>
<p>Man sollte niemals Membervariablen als Referenz zurück geben.</p>
</blockquote>
<p>Das würde ich nicht auf Const-Referenzen verallgemeinern (ich bin mir nicht sicher, ob du dich nur auf Referenzen auf unqualifizierte Objekte bezogen hast).</p>
</blockquote>
<p>Hmm. Ich schon. <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="😉"
    /><br />
Wenn die Referenz <code>const</code> ist, dann kannst du zwar den Inhalt nicht verändern, aber du hast immer noch Zugriff auf etwas, was eigentlich privat ist. Was ist, wenn jetzt eine Member des Objektes halt nicht genau so zurückgegeben werden soll, wie sie drin steht? - Also z.B noch ein Offset oder so dazu kommt. Das hast du mit einem getter voll unter Kontrolle, aber mit einer zurückgegeben Referenz nicht. Da müsstest du dann im Nachhinein das zurück gegebene Objekt nur noch als Proxy benutzen, und das eigentliche Objekt, das es mal war anderst benennen und dann das eigentliche, sowie das Proxy Objekt halten, welches dann auch immer die aktuellen Daten halten muss und kann sie nicht erst berechnen, wenn sie wirklich abgefragt wird.</p>
<p>Meine Meinung zu Kapselung. <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/1780006</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1780006</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Wed, 16 Sep 2009 17:48:52 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz auf Klassenattribut zurückliefern on Wed, 16 Sep 2009 18:09:50 GMT]]></title><description><![CDATA[<p>drakon schrieb:</p>
<blockquote>
<p>Was ist, wenn jetzt eine Member des Objektes halt nicht genau so zurückgegeben werden soll, wie sie drin steht? - Also z.B noch ein Offset oder so dazu kommt. Das hast du mit einem getter voll unter Kontrolle, aber mit einer zurückgegeben Referenz nicht.</p>
</blockquote>
<p>Aber es geht doch gerade um den Rückgabetyp eines getters?</p>
<pre><code class="language-cpp">mytype const&amp; get_member_ref(unsigned offset) const { return myData[offset]; }
</code></pre>
<p>So kann der Aufrufer entscheiden, ob er eine Kopie will, auf die er dann auch schreiben kann, oder eine Nur-Lesen-Referenz, wo garantiert nichts kopiert wird.<br />
Oder verstehe ich dich falsch?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1780016</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1780016</guid><dc:creator><![CDATA[Registrierter Troll]]></dc:creator><pubDate>Wed, 16 Sep 2009 18:09:50 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz auf Klassenattribut zurückliefern on Wed, 16 Sep 2009 18:25:38 GMT]]></title><description><![CDATA[<p>Aber was ist jetzt, wenn du nicht wirklich den Wert von myData[offset] zurückgeben willst, sondern halt noch ein wenig mehr (optimierung oder was auch immer..)</p>
<p>Dann musst du so etwas machen:</p>
<pre><code class="language-cpp">mytype const&amp; foo::get_member_ref(unsigned offset) const 
{ 
  mytype temp = myData[offset];
  temp.x + 0.1f; // oder sonst was
  return temp; 
}
</code></pre>
<p>Was ja offensichtilch böse ist. Also so etwas:</p>
<pre><code class="language-cpp">class foo
{
  ...
private:
 mytype myData[COUNT];
 mytype myData_offsets[COUNT];
};

mytype const&amp; get_member_ref(unsigned offset) const 
{ 
  return myData_offsets[offset];
}
</code></pre>
<p>Und hier darfst du, soblad sich myData ändert auch noch schauen, dass myData_offsets auch aktuell ist.</p>
<p>Und, wie du selber schon vermutest, ist das nicht so das wahre. <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="😉"
    /><br />
Es gibt natürlich Ausnahmen, wo sowas Sinn macht, aber nicht wenn man es vermeiden kann. (siehe z.B <code>std::string::c_str()</code> ).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1780023</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1780023</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Wed, 16 Sep 2009 18:25:38 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz auf Klassenattribut zurückliefern on Wed, 16 Sep 2009 18:48:49 GMT]]></title><description><![CDATA[<p>Jetzt verstehe ich, was du meinst.</p>
<p>In dem Fall würde man das Interface natürlich ändern. Macht aber nichts, weil man eine Referenz an den Rückgabewert einer Funktion binden kann und diese Referenz im aufrufenden Scope gültig bleibt.</p>
<pre><code class="language-cpp">mytype foo::get_data(unsigned offset) const // interface wurde geändert, vorher wars eine const-ref, jetzt ist es eine kopie
{
  mytype temp = myData[offset];
  temp.x + 0.1f;
  return temp;
}

int main()
{
    mytype const&amp; data = bar.get_data(42); // aufruf hat sich trotz interface-änderung nicht geändert
    std::cout &lt;&lt; data; // gültig
}
</code></pre>
<p>AFAIK ist das erlaubt!?<br />
Ich würde aber Referenzen sowieso nur dann zurückliefern, wenn ich solche Änderungen sicher ausschließen kann.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1780038</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1780038</guid><dc:creator><![CDATA[Registrierter Troll]]></dc:creator><pubDate>Wed, 16 Sep 2009 18:48:49 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz auf Klassenattribut zurückliefern on Wed, 16 Sep 2009 18:53:42 GMT]]></title><description><![CDATA[<p>Ja. Das darf man machen, allerdings könnte ja ein Schlaumeier kommen und das hier machen:</p>
<pre><code class="language-cpp">int main()
{
    mytype const* data = &amp;(bar.get_data(42));
    std::cout &lt;&lt; *data; // hups
}
</code></pre>
<p>Natürlich kann man hier jetzt argumentieren, dass der User dann selbst Schuld ist, aber man sollte dieses Riskiko nur eingehen, wenn man es wirklich braucht. Und das ist nicht der Fall, wenn man Angst vor Kopien hat.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1780045</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1780045</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Wed, 16 Sep 2009 18:53:42 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz auf Klassenattribut zurückliefern on Wed, 16 Sep 2009 20:49:05 GMT]]></title><description><![CDATA[<p>Ja, grundsätzlich stimmt das schon. Ich setze eigentlich auch eher Kopien ein, bei kleinen Objekten wie 2D-/3D-Vektoren etc. sowieso. Der Vorteil von Kopien ist, dass weniger potentielle Fehlerquellen (Referenz auf totes Objekt, ...) vorhanden sind und man einheitlich bleiben kann, falls mal etwas verändert werden soll. Aber wenn ich eine Klasse habe, die gewisse zusammengehörige Eigenschaften in einem Typ speichert, finde ich es okay, diesen als Const-Referenz zurückzugeben. Ein konkretes Beispiel bei mir sind Statusdaten einer Spielfigur in einem Spiel (Anzahl Leben, Punkte, gesammelte Gegenstände und solche Sachen). Da sehe ich keinen Sinn darin, eine unnötige Kopie anzulegen. Denn wenn grössere Dinge wie Container enthalten sind und man die Funktion oft braucht, kann das von der Performance her schon etwas ausmachen. Und ich gewinne im Normalfall nichts durch die Kopie.</p>
<p>Ich zumindest versuche Getter-Funktionen - egal welchen Rückgabetyps - möglichst allgemein anzuwenden. Also nicht etwa die Const-Referenz lange zwischenzuspeichern oder so. Meist benutze ich den zurückgegebenen Wert gleich in einem temporären Ausdruck, damit er sicher noch existiert, oder ich erstelle eine lokale Kopie, um die Lebensdauer zu verlängern. Eine Kopie kann man ja immer noch erstellen, aber man wird nicht dazu gezwungen, wenns nicht nötig ist. Wenn ich selber etwas schreibe, erwarte vom Benutzer aber auch, dass er nicht irgendwelche Annahmen bezüglich Lebensdauer oder Gültigkeit trifft, wenn eine Referenz im Spiel ist. Im Zweifelsfalle sollte man sowieso die Dokumentation anschauen. Und solange man Const-Referenz-Rückgabetypen keine besondere Behandlung zukommen lässt, ist es auch kein Problem, die Schnittstelle falls nötig doch zu einer Kopie zu ändern (nur rekompilieren). Allerdings habe ich bisher fast nie solche Änderungen durchführen müssen.</p>
<p>Ein ganz anderes Argument: Bei einigen Typen ist eine Kopie aus semantischen Gründen nicht angebracht - vielleicht, weil sie gewisse Seiteneffekte mit sich bringt - oder weil das Objekt schlicht und einfach nicht kopierbar ist.</p>
<p>Also zusammengefasst: Ich bin nicht der Meinung, dass Const-Referenzen die Kapselung grundsätzlich verletzen. Ich wäge den konkreten Fall ab; dabei spielt ein Rolle, wie gross das zurückgegebene Objekt ist, wer den Code benutzt oder wie wichtig Geschwindigkeit jeweils ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1780120</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1780120</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Wed, 16 Sep 2009 20:49:05 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz auf Klassenattribut zurückliefern on Thu, 17 Sep 2009 19:13:51 GMT]]></title><description><![CDATA[<p>Ich benutze sie ja auch. Ich habe nur dagegen argumentiert, dass es die Kapselung nicht beeinträchtigt. Es gibt viele gute Gründe, dass man eben doch const Referenzen benutzt und wenn man davon ausgeht, dass der Benutzer (oftmals ja einer selbst) sich der Probleme bewusst ist, dann ist es auch nicht so tragisch.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1780696</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1780696</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Thu, 17 Sep 2009 19:13:51 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz auf Klassenattribut zurückliefern on Thu, 17 Sep 2009 19:16:58 GMT]]></title><description><![CDATA[<p>Du hast völlig Recht. Ich wollte ursprünglich nur Artchis Aussage, man solle nie Referenzen zurückgeben, etwas relativieren. Vielleicht hab ich das dann später etwas zu sehr auf die Kapselung bezogen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1780699</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1780699</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Thu, 17 Sep 2009 19:16:58 GMT</pubDate></item></channel></rss>