<?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[virtuelle Methoden: unterschiedlicher Rückgabetyp]]></title><description><![CDATA[<p>Hi!</p>
<p>In einer Basisklasse &quot;Ober&quot; habe ich folgende virtuelle Methode:</p>
<pre><code class="language-cpp">virtual Ober&amp; assign(const Ober&amp; rs)
{/*...*/}
</code></pre>
<p>In einer davon abgeleiteten Klasse &quot;Unter&quot; sieht die entsprechende Methode so aus:</p>
<pre><code class="language-cpp">Unter&amp; assign(const Ober&amp; rs)
{/*...*/}
</code></pre>
<p>Meinem Compiler gefällt das leider nicht:</p>
<pre><code>error C2555: 'Unter::assign' : Neue Version der virtuellen Funktion unterscheidet sich von 'Ober::assign' nur hinsichtlich des Ergebnistyps oder der Aufrufkonvention
</code></pre>
<p>Natürlich ist der Rückgabetyp unterschiedlich, allerdings dachte ich, das sei die einzig zulässige Ausnahme:<br />
Hat die virtuelle Funktion Rückgabetyp &quot;Referenz auf Klasse&quot;, darf der Rückgabetyp der entsprechenden Funktion in der abgeleiteten Klasse &quot;Referenz auf abgeleitete Klasse&quot; sein (genauso für Zeiger).</p>
<p>Wäre nett, wenn mir jemand erklären könnte, was hier schief läuft.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/129242/virtuelle-methoden-unterschiedlicher-rückgabetyp</link><generator>RSS for Node</generator><lastBuildDate>Wed, 26 Aug 2026 04:27:26 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/129242.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 11 Dec 2005 19:44:28 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to virtuelle Methoden: unterschiedlicher Rückgabetyp on Sun, 11 Dec 2005 19:44:28 GMT]]></title><description><![CDATA[<p>Hi!</p>
<p>In einer Basisklasse &quot;Ober&quot; habe ich folgende virtuelle Methode:</p>
<pre><code class="language-cpp">virtual Ober&amp; assign(const Ober&amp; rs)
{/*...*/}
</code></pre>
<p>In einer davon abgeleiteten Klasse &quot;Unter&quot; sieht die entsprechende Methode so aus:</p>
<pre><code class="language-cpp">Unter&amp; assign(const Ober&amp; rs)
{/*...*/}
</code></pre>
<p>Meinem Compiler gefällt das leider nicht:</p>
<pre><code>error C2555: 'Unter::assign' : Neue Version der virtuellen Funktion unterscheidet sich von 'Ober::assign' nur hinsichtlich des Ergebnistyps oder der Aufrufkonvention
</code></pre>
<p>Natürlich ist der Rückgabetyp unterschiedlich, allerdings dachte ich, das sei die einzig zulässige Ausnahme:<br />
Hat die virtuelle Funktion Rückgabetyp &quot;Referenz auf Klasse&quot;, darf der Rückgabetyp der entsprechenden Funktion in der abgeleiteten Klasse &quot;Referenz auf abgeleitete Klasse&quot; sein (genauso für Zeiger).</p>
<p>Wäre nett, wenn mir jemand erklären könnte, was hier schief läuft.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/939790</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/939790</guid><dc:creator><![CDATA[Nanuq]]></dc:creator><pubDate>Sun, 11 Dec 2005 19:44:28 GMT</pubDate></item><item><title><![CDATA[Reply to virtuelle Methoden: unterschiedlicher Rückgabetyp on Sun, 11 Dec 2005 20:06:33 GMT]]></title><description><![CDATA[<p>hi,</p>
<p>Man kann nicht nur den Rückgabetyp ändern.<br />
Du kannst aber in der abgeleiteten Klassen die selbe Funktion benutzen und innerhalb der Funktion ein return Derived benutzen, da dann Derived automatisch in der Hierarchie upgecastet wird.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/939812</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/939812</guid><dc:creator><![CDATA[bluecode]]></dc:creator><pubDate>Sun, 11 Dec 2005 20:06:33 GMT</pubDate></item><item><title><![CDATA[Reply to virtuelle Methoden: unterschiedlicher Rückgabetyp on Sun, 11 Dec 2005 20:10:50 GMT]]></title><description><![CDATA[<p>Um so weniger verstehe ich dann die Fehlermeldung des Compilers...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/939814</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/939814</guid><dc:creator><![CDATA[Nanuq]]></dc:creator><pubDate>Sun, 11 Dec 2005 20:10:50 GMT</pubDate></item><item><title><![CDATA[Reply to virtuelle Methoden: unterschiedlicher Rückgabetyp on Sun, 11 Dec 2005 20:16:18 GMT]]></title><description><![CDATA[<p>hi,</p>
<p>ich meins so:</p>
<p>Basisklasse (Ober):</p>
<pre><code class="language-cpp">virtual Ober&amp; assign(const Ober&amp; rs){/*don't look here, it's top secret*/}
</code></pre>
<p>abgeleitete Klasse (Unter):</p>
<pre><code class="language-cpp">virtual Ober&amp; assign(const Ober&amp; rs){return Unter;}
</code></pre>
<p>In der abgeleiteten Klasse wird bei dem return die Unterklasse in eine Oberklasse gecastet und zurückgegeben. Du brauchst also keine verschiedenen return-typen, da &quot;Unter&quot; ein &quot;Ober&quot; ist.</p>
<p>[edit: code tags]</p>
]]></description><link>https://www.c-plusplus.net/forum/post/939815</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/939815</guid><dc:creator><![CDATA[bluecode]]></dc:creator><pubDate>Sun, 11 Dec 2005 20:16:18 GMT</pubDate></item><item><title><![CDATA[Reply to virtuelle Methoden: unterschiedlicher Rückgabetyp on Mon, 12 Dec 2005 18:07:32 GMT]]></title><description><![CDATA[<p>Ok, ich denke ich muss doch ein wenig ausholen und das ganze Problem beschreiben: ich habe in einem Lehrbuch ein Kapitel über &quot;Zuweisungsoperator und Vererbung&quot; gelesen. Das folgende Beispiel sollte dabei demonstrieren, wie man das Zuweisungsproblem lösen kann, wenn die Zuweisung auch für polymorphe Objekte funktionieren soll.<br />
Ich denke, einige der Fragen, die ich dazu habe, würden sich klären, wenn ich das debuggen könnte, allerdings bringt mir mein Compiler die oben erwähnte Fehlermeldung.</p>
<pre><code class="language-cpp">class Ober
{
public:
	Ober(int io)
		: iO(io){}

    virtual Ober&amp; assign(const Ober&amp; rs)
	{
		if(this != &amp;rs)
		{
			lokaleZuweisung(rs);
		}
		return *this;
    }

    Ober&amp; operator=(const Ober&amp; rs) { return assign(rs); }

protected:
	void lokaleZuweisung(const Ober&amp; rs)
	{
		iO = rs.iO;
    }

private:
	int iO;   // Daten speziell für Ober
};
</code></pre>
<pre><code class="language-cpp">class Unter : public Ober
{
public:
	Unter(int io, int iu)
		: Ober(io), iU(iu) {}

    virtual Unter&amp; assign(const Ober&amp; rs)
	{
		if(this != &amp;rs)
		{
			Ober::assign(rs);        // Oberklassensubobjekt
			/* Die rechte Seite rs wird hier zur Laufzeit in eine
			Referenz rs mit dem erforderlichen Typ gewandelt.  rs
			gehört zur Klasse Unter, so dass der Compiler ab hier
			keine Typkonflikte mehr hat.*/
			const Unter&amp; U = dynamic_cast&lt;const Unter&amp;&gt;(rs);
			lokaleZuweisung(U);      // nur lokale Daten
       }
       return *this;
    }

    // um Generierung des impliziten Operators zu vermeiden,
    // muss Unter&amp; operator=(const Unter&amp; rs) existieren.
    Unter&amp; operator=(const Unter&amp; rs) { return assign(rs); }

protected:
    void lokaleZuweisung(const Unter&amp; rs)
	{
		iU = rs.iU;
    }

private:
    int iU;   // Daten speziell für Unter
};
</code></pre>
<p>Nehmen wir an, ich hätte folgende Variablendeklarationen:</p>
<pre><code class="language-cpp">Unter U1, U2;
Ober  O1, O2;
Ober&amp; rO = U2; // polymorph
</code></pre>
<p>Und folgende Zuweisungen (mit den Fragen, die sich dabei für mich ergeben):</p>
<pre><code class="language-cpp">O1 = O2;  // kein Problem, verstehe ich :-)
U1 = U2;  // dito
O1 = U1;  // funktioniert, ich muss mir halt klar sein, dass ich Information verliere
U1 = O1;  // ohnehin verboten =&gt; Fehler
// jetzt kommen die interessanten Fälle
O1 = rO;  // zunächst wird Ober::operator=() aufgerufen, 
          // der ruft assign(rO) auf und weil assign virtuell ist, wird
          // Unter::assign() aufgerufen. Das liefert Unter&amp; zurück und
          // ich habe wieder den Fall O1 = U1. Ist das korrekt?
          // Weitere Frage: was ist in diesem Fall this? Das temporäre Objekt,
          // das in return assign(rs) steckt?
U1 = rO;  // es wird Unter::operator=() augerufen und wenn die vorherige
          // Zuweisung korrekt beschrieben war, ist mir diese auch klar ;-)
</code></pre>
<p>Wäre nett, wenn mich jemand bestätigen oder den Müll, den ich da erzähle korrigieren könnte!!</p>
<p>Und meine anfängliche Frage bleibt: warum beschwert sich der Compiler und was tue ich dagegen ohne Folgefehler zu erhalten?</p>
<p>Vielen Dank schon mal vorab!!!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/940457</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/940457</guid><dc:creator><![CDATA[Nanuq]]></dc:creator><pubDate>Mon, 12 Dec 2005 18:07:32 GMT</pubDate></item><item><title><![CDATA[Reply to virtuelle Methoden: unterschiedlicher Rückgabetyp on Mon, 12 Dec 2005 18:26:51 GMT]]></title><description><![CDATA[<p>Das ist ein Bug in älteren Versionen von Visual C++:<br />
<a href="http://support.microsoft.com/?scid=kb%3Ben-us%3B240862" rel="nofollow">http://support.microsoft.com/?scid=kb%3Ben-us%3B240862</a></p>
<p>Mit Visual <a href="http://C++.NET" rel="nofollow">C++.NET</a> 2003 geht das.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/940475</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/940475</guid><dc:creator><![CDATA[MFK]]></dc:creator><pubDate>Mon, 12 Dec 2005 18:26:51 GMT</pubDate></item><item><title><![CDATA[Reply to virtuelle Methoden: unterschiedlicher Rückgabetyp on Mon, 12 Dec 2005 18:37:12 GMT]]></title><description><![CDATA[<p>Das ist ja interessant! Und ärgerlich für mich <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 />
Trotzdem danke für die Info!!</p>
<p>Da ein Debug also auch zukünftig nicht möglich sein wird, wäre ich jetzt noch dankbar, wenn sich jemand zu meinen Kommentaren im letzten Quellcodeblock äußern könnte...</p>
<p>MfG,<br />
Nanuq</p>
]]></description><link>https://www.c-plusplus.net/forum/post/940489</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/940489</guid><dc:creator><![CDATA[Nanuq]]></dc:creator><pubDate>Mon, 12 Dec 2005 18:37:12 GMT</pubDate></item><item><title><![CDATA[Reply to virtuelle Methoden: unterschiedlicher Rückgabetyp on Tue, 13 Dec 2005 07:48:45 GMT]]></title><description><![CDATA[<p>Nanuq schrieb:</p>
<blockquote>
<pre><code class="language-cpp">O1 = O2;  // kein Problem, verstehe ich :-)
U1 = U2;  // dito
O1 = U1;  // funktioniert, ich muss mir halt klar sein, dass ich Information verliere
U1 = O1;  // ohnehin verboten =&gt; Fehler
</code></pre>
</blockquote>
<p>Bis hierher dürfte es richtig sein.</p>
<blockquote>
<pre><code class="language-cpp">O1 = rO;  // zunächst wird Ober::operator=() aufgerufen, 
          // der ruft assign(rO) auf und weil assign virtuell ist, wird
          // Unter::assign() aufgerufen. Das liefert Unter&amp; zurück und
          // ich habe wieder den Fall O1 = U1. Ist das korrekt?
          // Weitere Frage: was ist in diesem Fall this? Das temporäre Objekt,
          // das in return assign(rs) steckt?
</code></pre>
</blockquote>
<p>Nein, das ruft Ober::assign(r0) auf (wichtig ist hierfür der Typ links vom Gleichheitszeichen)</p>
<blockquote>
<pre><code class="language-cpp">U1 = rO;  // es wird Unter::operator=() augerufen und wenn die vorherige
          // Zuweisung korrekt beschrieben war, ist mir diese auch klar ;-)
</code></pre>
</blockquote>
<p>Das dürfte genauso in die Hose gehen wie &quot;U1=O1;&quot; (ob es möglich ist, entscheiden die statischen Typen der Objekte).</p>
<p>btw, interessanter dürfte die Zuweisung &quot;rO=O1;&quot; sein - hier greift das virtual und du rufst Unter::assign mit einem echten Ober-Objekt auf -&gt; Crash (bzw. Exception im dynamic_cast).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/940767</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/940767</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Tue, 13 Dec 2005 07:48:45 GMT</pubDate></item><item><title><![CDATA[Reply to virtuelle Methoden: unterschiedlicher Rückgabetyp on Tue, 13 Dec 2005 12:22:18 GMT]]></title><description><![CDATA[<p>Danke erstmal für's durchlesen!</p>
<p>CStoll schrieb:</p>
<blockquote>
<blockquote>
<pre><code class="language-cpp">O1 = rO;  // zunächst wird Ober::operator=() aufgerufen, 
          // der ruft assign(rO) auf und weil assign virtuell ist, wird
          // Unter::assign() aufgerufen. Das liefert Unter&amp; zurück und
          // ich habe wieder den Fall O1 = U1. Ist das korrekt?
          // Weitere Frage: was ist in diesem Fall this? Das temporäre Objekt,
          // das in return assign(rs) steckt?
</code></pre>
</blockquote>
<p>Nein, das ruft Ober::assign(r0) auf (wichtig ist hierfür der Typ links vom Gleichheitszeichen)</p>
</blockquote>
<p>Ok, verstehe ich: links des Gleichheitszeichens steht ein &quot;Ober&quot; deshalb zuerst Aufruf Ober::operator=(rO), innerhalb der Methode dann Ober::assign(rO), d.h. die zusätzlichen Attribute von &quot;Unter&quot; gehen wie im Fall O1=U1 verloren.</p>
<p>CStoll schrieb:</p>
<blockquote>
<blockquote>
<pre><code class="language-cpp">U1 = rO;  // es wird Unter::operator=() augerufen und wenn die vorherige
          // Zuweisung korrekt beschrieben war, ist mir diese auch klar ;-)
</code></pre>
</blockquote>
<p>Das dürfte genauso in die Hose gehen wie &quot;U1=O1;&quot; (ob es möglich ist, entscheiden die statischen Typen der Objekte).</p>
</blockquote>
<p>Das heißt, hier scheitert bereits der Aufruf von Unter::operator=(rO), weil ein &quot;Unter&quot; als Übergabe erwartet, aber (statisch gesehen) ein &quot;Ober&quot; übergeben wird, sodass assign(rO) gar nicht erst aufgerufen wird??</p>
<p>CStoll schrieb:</p>
<blockquote>
<p>btw, interessanter dürfte die Zuweisung &quot;rO=O1;&quot; sein - hier greift das virtual und du rufst Unter::assign mit einem echten Ober-Objekt auf -&gt; Crash (bzw. Exception im dynamic_cast).</p>
</blockquote>
<p>Das klingt logisch! D.h. die vom Autor des Buches angegebene Lösung einer Zuweisung, die auch für polymorphe Objekte funktioniert, ist ziemlicher Blödsinn, weil sie für die beiden Fälle</p>
<pre><code class="language-cpp">U1=rO;
rO=O1;
</code></pre>
<p>nicht funktioniert und die virtuelle Funktion assign eigetnlich überhaupt keinen Nutzen hat...<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 />
Vielleicht sollte ich mich nach einem anderen Buch umschauen...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/940981</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/940981</guid><dc:creator><![CDATA[Nanuq]]></dc:creator><pubDate>Tue, 13 Dec 2005 12:22:18 GMT</pubDate></item></channel></rss>