<?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[polsmorphe klasse mit operator=()]]></title><description><![CDATA[<p>Hi!</p>
<p>Es sei eine Basisklasse:</p>
<pre><code class="language-cpp">class A
{
public:
   A() : x(10) {}

   virtual int Get() { return x; }

   A&amp; operator=(const A&amp; right)
   {
      x = right.x;
      return *this;
   }

protected:
   int x;
};
</code></pre>
<p>Diese Klasse soll jetzt abgeleitet werden.</p>
<pre><code class="language-cpp">class B : public A
{
public:
   B() : y(11) {}

   virtual int Get() { return x+y; }

   B&amp; operator=(const B&amp; right)
   {
      y = right.y;
      A::operator=(right);
      return *this;
   }

protected:
   int y;
};
</code></pre>
<p>Das funktioniert. Die Klassen sind polymorph, zumindest solange ich folgendes nicht mache (die A* Zeiger stehen stellvertrend dafür, daß A und alle ihre derivate in einer Hierarchie/Liste eingehängt werden, in denen sie durch Zeiger auf A referenziert werden):</p>
<pre><code class="language-cpp">void main()
{
   B b1;
   B b2;

   A* ptr1 = &amp;b1;
   A* ptr2 = &amp;b2;

   *ptr1 = *ptr2; // Soll sozusagen virtuell aufgerufen werden
}
</code></pre>
<p>Das knackt mir die Polymorphie. Das Virtualisieren der operator=() Methoden hilft hier nicht, da die Methoden einander (wegen unterschiedlicher Signaturen) nicht zugeordnet werden.</p>
<p>Ich will den Code ändern und zwar so, daß auch obiger Zugriff möglich ist. Immerhin sollen die Klassen polymorph sein auch bei einer Zuweisung.</p>
<p>Geht das ohne dynamic_cast&lt;&gt;()?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/161829/polsmorphe-klasse-mit-operator</link><generator>RSS for Node</generator><lastBuildDate>Sat, 12 Sep 2026 03:11:01 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/161829.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 11 Oct 2006 13:13:40 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to polsmorphe klasse mit operator=() on Wed, 11 Oct 2006 13:13:40 GMT]]></title><description><![CDATA[<p>Hi!</p>
<p>Es sei eine Basisklasse:</p>
<pre><code class="language-cpp">class A
{
public:
   A() : x(10) {}

   virtual int Get() { return x; }

   A&amp; operator=(const A&amp; right)
   {
      x = right.x;
      return *this;
   }

protected:
   int x;
};
</code></pre>
<p>Diese Klasse soll jetzt abgeleitet werden.</p>
<pre><code class="language-cpp">class B : public A
{
public:
   B() : y(11) {}

   virtual int Get() { return x+y; }

   B&amp; operator=(const B&amp; right)
   {
      y = right.y;
      A::operator=(right);
      return *this;
   }

protected:
   int y;
};
</code></pre>
<p>Das funktioniert. Die Klassen sind polymorph, zumindest solange ich folgendes nicht mache (die A* Zeiger stehen stellvertrend dafür, daß A und alle ihre derivate in einer Hierarchie/Liste eingehängt werden, in denen sie durch Zeiger auf A referenziert werden):</p>
<pre><code class="language-cpp">void main()
{
   B b1;
   B b2;

   A* ptr1 = &amp;b1;
   A* ptr2 = &amp;b2;

   *ptr1 = *ptr2; // Soll sozusagen virtuell aufgerufen werden
}
</code></pre>
<p>Das knackt mir die Polymorphie. Das Virtualisieren der operator=() Methoden hilft hier nicht, da die Methoden einander (wegen unterschiedlicher Signaturen) nicht zugeordnet werden.</p>
<p>Ich will den Code ändern und zwar so, daß auch obiger Zugriff möglich ist. Immerhin sollen die Klassen polymorph sein auch bei einer Zuweisung.</p>
<p>Geht das ohne dynamic_cast&lt;&gt;()?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1152905</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1152905</guid><dc:creator><![CDATA[Jordy]]></dc:creator><pubDate>Wed, 11 Oct 2006 13:13:40 GMT</pubDate></item><item><title><![CDATA[Reply to polsmorphe klasse mit operator=() on Wed, 11 Oct 2006 14:23:48 GMT]]></title><description><![CDATA[<p>Du könntest es mit einer virtuellen Funktion probieren, die die eigentliche Zuweisungsarbeit übernimmt.</p>
<pre><code class="language-cpp">class A
{
protected:
	virtual void assign(const A&amp; rhs)
	{
		x = rhs.x;
	}
public:
	A&amp; operator =(const A&amp; rhs)
	{
		assign(rhs);
		return *this;
	}
};

class B
	: public A
{
protected:
	void assign(const A&amp; rhs)
	{
		A::assign(rhs);
		y = static_cast&lt;const B&amp;&gt;(rhs).y;
	}
public:
	B&amp; operator =(const B&amp; rhs)
	{
		assign(rhs);
		return *this;
	}
};
</code></pre>
<p>Wobei das nicht hundertprozentig sicher ist, bei Zuweisungen wie B = A gibt es zB Probleme. Kann man aber sicherlich noch beseitigen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1152949</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1152949</guid><dc:creator><![CDATA[groovemaster]]></dc:creator><pubDate>Wed, 11 Oct 2006 14:23:48 GMT</pubDate></item><item><title><![CDATA[Reply to polsmorphe klasse mit operator=() on Wed, 11 Oct 2006 16:20:58 GMT]]></title><description><![CDATA[<p>Die Frage ist doch, was soll das dann bedeuten?</p>
<pre><code class="language-cpp">Fahrzeug * f = new Schiff;
Auto * a = new Auto;
*f=*a; // soll Fahrzeug jetzt plötzlich ein Auto sein?
*a=*f; // wie kann aus einem Fahrzeug ein Auto werden, das geht doch garnicht immer. Wenn beispielsweise Fahrzeug in Wirklichkeit ein Schiff ist.
</code></pre>
<p>Nach meiner Erfahrung sollte man für polymorphe Typen lieber auf die meisten Operatorenüberladungen verzichten. Man muß letztlich eh mit Zeigern oder Referenzen arbeiten, um korrekt mit den Teilen umgehen zu können.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1153012</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1153012</guid><dc:creator><![CDATA[Jester]]></dc:creator><pubDate>Wed, 11 Oct 2006 16:20:58 GMT</pubDate></item><item><title><![CDATA[Reply to polsmorphe klasse mit operator=() on Thu, 12 Oct 2006 10:53:16 GMT]]></title><description><![CDATA[<p>Jester schrieb:</p>
<blockquote>
<p>Die Frage ist doch, was soll das dann bedeuten?</p>
<pre><code class="language-cpp">Fahrzeug * f = new Schiff;
Auto * a = new Auto;
*f=*a; // soll Fahrzeug jetzt plötzlich ein Auto sein?
*a=*f; // wie kann aus einem Fahrzeug ein Auto werden, das geht doch garnicht immer. Wenn beispielsweise Fahrzeug in Wirklichkeit ein Schiff ist.
</code></pre>
<p>Nach meiner Erfahrung sollte man für polymorphe Typen lieber auf die meisten Operatorenüberladungen verzichten. Man muß letztlich eh mit Zeigern oder Referenzen arbeiten, um korrekt mit den Teilen umgehen zu können.</p>
</blockquote>
<pre><code class="language-cpp">Fahrzeug * f1 = new Schiff;
Fahrzeug * f2 = new Schiff;
Fahrzeug * f3 = new Auto;
*f1=*f2; // Hier soll das ganze schiff kopiert werden, nicht nur ein Teil!
*f2=*f3; // Hier nur die gemeinsame basis (wenn sowas jemand macht)
</code></pre>
<p>Ich will einfach verhindern, daß jemand, der die Objekte (sie sind ja polymorph, das heißt sie werden überlicherweise über basiszeiger gehandhabt) über basiszeiger einander zuweist, den linken operanden in einen illegalen zustand versetzt. Wenn er zwei objekte *gleichen* typs zuweist, soll auch *alles* kopiert werden, nicht nur die basis.</p>
<p>Oder anders forumliert: Ich will, daß polymorphe Klasse, sich immer polymorph verhalten, auch bei operator-aufrufen.</p>
<p>Das heißt wohl, wenn ich polymorphe klassen schreibe, die ich einander zuweisen möchte, muss ich letztendlich über zeiger und dynamic_cast&lt;&gt;() gehen? Igitt.</p>
<p>Oder umgekehrt: Polymorphe Objekte dürfen niemals einen operator=() besitzen, weil man sonst jede Menge Unsinn machen kann? Das wäre ja noch schlimmer.</p>
<p>Mir ist nie aufgefallen, daß polymorphe Objekte so untauglich für handle-by-value sind. Mir scheint das wäre nur sauber lösbar, wenn für die parameter virtueller methoden (und damit für operanden) polymorphie erlaubt wäre (so wie es für den *Rückgabewert* virtueller methoden ja inzwischen erlaubt ist).</p>
<p>Gibt es für sowas kein Lösungsmuster (ohne dynamic_cast)?!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1153405</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1153405</guid><dc:creator><![CDATA[Jordy]]></dc:creator><pubDate>Thu, 12 Oct 2006 10:53:16 GMT</pubDate></item><item><title><![CDATA[Reply to polsmorphe klasse mit operator=() on Thu, 12 Oct 2006 10:54:30 GMT]]></title><description><![CDATA[<p>groovemaster schrieb:</p>
<blockquote>
<p>Du könntest es mit einer virtuellen Funktion probieren, die die eigentliche Zuweisungsarbeit übernimmt.<br />
Wobei das nicht hundertprozentig sicher ist, bei Zuweisungen wie B = A gibt es zB Probleme. Kann man aber sicherlich noch beseitigen.</p>
</blockquote>
<p>Ohne dynamic_cast? wie?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1153407</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1153407</guid><dc:creator><![CDATA[Jordy]]></dc:creator><pubDate>Thu, 12 Oct 2006 10:54:30 GMT</pubDate></item><item><title><![CDATA[Reply to polsmorphe klasse mit operator=() on Thu, 12 Oct 2006 11:03:03 GMT]]></title><description><![CDATA[<p>man verwendet keine operatoren ueberladung in polymorphen klassen weil man damit dem sinn der polymorphie entgegen wirkt.</p>
<p>Wenn ich sage:</p>
<p>ein Auto ist ein Fahrzeug<br />
und<br />
ein Fahrrad ist ein Fahrzeug</p>
<p>dann macht es keinen Sinn zu sagen Auto A = Fahrrad B<br />
Du muesstest hier also eine Exception fliegen lassen.</p>
<p>Aber genau das ist ja eigentlich der Vorteil von Polymorphie gewesen, dass es mir komplett egal sein kann ob dieses Fahrzeug ein Auto oder Fahrrad ist. Wenn ich den Upcast auf Fahrzeug mache, gebe ich das Wissen um den genauen Typen auf und ich will alle Typen gleich behandeln. Weil ja alles Fahrzeuge sind.</p>
<p>Es waere sehr verwirrend wenn ich<br />
Fahrzeug A= Fahrzeug B<br />
machen kann aber<br />
Fahrzeug A = Fahrzeug C<br />
nicht.</p>
<p>Wenn du bei polymorphen Klassen kopieren willst, dann verwende eine &quot;clone&quot; methode (wie in Java).</p>
<p>oder gib die Polymorphie auf. Du kannst nicht beides haben und zusaetzlich noch ordentlichen Code. Du kannst zwar mit dynamic_cast und sonstigen rtti sachen dir etwas zusammen hacken - aber sowas sollte immer stark hinterfragt werden ob es wirklich noetig ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1153417</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1153417</guid><dc:creator><![CDATA[Shade Of Mine]]></dc:creator><pubDate>Thu, 12 Oct 2006 11:03:03 GMT</pubDate></item><item><title><![CDATA[Reply to polsmorphe klasse mit operator=() on Thu, 12 Oct 2006 11:06:16 GMT]]></title><description><![CDATA[<p>Shade Of Mine schrieb:</p>
<blockquote>
<p>Wenn du bei polymorphen Klassen kopieren willst, dann verwende eine &quot;clone&quot; methode (wie in Java).</p>
</blockquote>
<p>Naja, eine Clone-Methode würde letzlich auch nichts anderes machen, als per dynamic_cast&lt;&gt;() den typ festellen und über einen Kopier-konstruktor eine neues Objekt erzeugen, oder?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1153421</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1153421</guid><dc:creator><![CDATA[Jordy]]></dc:creator><pubDate>Thu, 12 Oct 2006 11:06:16 GMT</pubDate></item><item><title><![CDATA[Reply to polsmorphe klasse mit operator=() on Thu, 12 Oct 2006 11:07:43 GMT]]></title><description><![CDATA[<p>Erzähl doch mal ein paar Worte über die Notwendigkeit dieser Kopieraktionen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1153426</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1153426</guid><dc:creator><![CDATA[Knuddlbaer]]></dc:creator><pubDate>Thu, 12 Oct 2006 11:07:43 GMT</pubDate></item><item><title><![CDATA[Reply to polsmorphe klasse mit operator=() on Thu, 12 Oct 2006 11:11:31 GMT]]></title><description><![CDATA[<p>Jordy schrieb:</p>
<blockquote>
<p>Naja, eine Clone-Methode würde letzlich auch nichts anderes machen, als per dynamic_cast&lt;&gt;() den typ festellen und über einen Kopier-konstruktor eine neues Objekt erzeugen, oder?</p>
</blockquote>
<p>nicht wirklich:</p>
<pre><code class="language-cpp">class Base {
public:
  virtual Base* clone() = 0;
};

class Derived : public Base {
public:
  virtual Derived* clone() {
    return new Derived(*this);
  }
};
</code></pre>
<p>wobei du natuerlich dir irgendetwas fuer das memory management ueberlegen musst...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1153432</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1153432</guid><dc:creator><![CDATA[Shade Of Mine]]></dc:creator><pubDate>Thu, 12 Oct 2006 11:11:31 GMT</pubDate></item><item><title><![CDATA[Reply to polsmorphe klasse mit operator=() on Thu, 12 Oct 2006 12:51:53 GMT]]></title><description><![CDATA[<p>Das Clone() wäre eine recht gute lösung, für das Zuweisen/Kopieren.</p>
<p>Dumm wird es, wenn ich auch noch per == vergleichen will (ebenfalls tief). Das scheint mir nur mit widerlichem casten möglich zu sein, oder nicht?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1153562</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1153562</guid><dc:creator><![CDATA[Jordy]]></dc:creator><pubDate>Thu, 12 Oct 2006 12:51:53 GMT</pubDate></item><item><title><![CDATA[Reply to polsmorphe klasse mit operator=() on Thu, 12 Oct 2006 12:59:43 GMT]]></title><description><![CDATA[<p>In der Überschrift 2.0 ist ein Rechtschreibfehler 2.0: pol<strong>y</strong>morphe</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1153573</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1153573</guid><dc:creator><![CDATA[Korrektor 2.0]]></dc:creator><pubDate>Thu, 12 Oct 2006 12:59:43 GMT</pubDate></item><item><title><![CDATA[Reply to polsmorphe klasse mit operator=() on Thu, 12 Oct 2006 14:28:34 GMT]]></title><description><![CDATA[<p>Jordy schrieb:</p>
<blockquote>
<p>Dumm wird es, wenn ich auch noch per == vergleichen will (ebenfalls tief). Das scheint mir nur mit widerlichem casten möglich zu sein, oder nicht?</p>
</blockquote>
<p>Wie willst du sinnvoll ein Auto mit einem Boot vergleichen?</p>
<p>Oder was viel interessanter ist:</p>
<p>ein Auto mit einem CountDoorOpens_Auto - wo die Anzahl der tueroeffnungen mitgezaehlt wird, vergleichen. Sind die beiden jetzt identisch? oder sind sie unterschiedlich.</p>
<p>Es klappt nicht gut. Du hast weit mehr probleme als ein paar casts...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1153676</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1153676</guid><dc:creator><![CDATA[Shade Of Mine]]></dc:creator><pubDate>Thu, 12 Oct 2006 14:28:34 GMT</pubDate></item><item><title><![CDATA[Reply to polsmorphe klasse mit operator=() on Thu, 12 Oct 2006 14:42:01 GMT]]></title><description><![CDATA[<p>Shade Of Mine schrieb:</p>
<blockquote>
<p>Jordy schrieb:</p>
<blockquote>
<p>Dumm wird es, wenn ich auch noch per == vergleichen will (ebenfalls tief). Das scheint mir nur mit widerlichem casten möglich zu sein, oder nicht?</p>
</blockquote>
<p>Wie willst du sinnvoll ein Auto mit einem Boot vergleichen?</p>
<p>Oder was viel interessanter ist:</p>
<p>ein Auto mit einem CountDoorOpens_Auto - wo die Anzahl der tueroeffnungen mitgezaehlt wird, vergleichen. Sind die beiden jetzt identisch? oder sind sie unterschiedlich.</p>
<p>Es klappt nicht gut. Du hast weit mehr probleme als ein paar casts...</p>
</blockquote>
<p>Ich würde wollen, daß ich bei verschiedenen Objekten immer false heraus kommt. Wie vergleicht man einen Container?: Anzahl objekte, sonstige member des Containers, Inhalt der Objekte und bei polymorphen objekten eben auch deren typ.</p>
<p>Und nichts anderes will ich tun. Ich will einen Container für polymorphe objekte entwerfen, den man per = kopieren kann und den man mit == vergleichen kann. Beides tief. Um das tun zu können, müssen die polymorphen objekte eben virtuell zuweisbar sein und virtuell vergleichbar sein. Beides scheint nicht möglich zu sein.</p>
<p>Immerhin bin ich mit dem Clone() etwas weiter gekommen. So kann ich einen Container elegant clonen.<br />
Aber von obigen Ziel bin ich trotzdem noch weit entfernt:</p>
<ol>
<li>Virtuells Vergleichen ist nicht möglich.</li>
<li>Den Container kann ich auch nur so lange mit = zuweisen, solange er selbst nicht auch abgeleitet wird, was aber möglich sein soll, denn ich hätte gerne einen Container, der abgeleitete Objekte seiner selbst verwalten kann.</li>
</ol>
]]></description><link>https://www.c-plusplus.net/forum/post/1153688</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1153688</guid><dc:creator><![CDATA[Jordy]]></dc:creator><pubDate>Thu, 12 Oct 2006 14:42:01 GMT</pubDate></item><item><title><![CDATA[Reply to polsmorphe klasse mit operator=() on Thu, 12 Oct 2006 15:06:17 GMT]]></title><description><![CDATA[<p>wenn du von objekten den gleichen typ verlangst damit sie gleich sind (was wie schon gesagt ob ein problemdarstellt, zB wenn du eine Klasse nur um funktionalitaet, nicht aber um state erweiterst).</p>
<p>ich denke ganz ehrlich, dass dein design irgendwie kaputt ist</p>
<p>mittels typeid() kannst du testen ob der typ von 2 referenzen gleich ist. Damit kannst du dann ein compare mit downcast machen...</p>
<p>aber du wirst damit viele probleme bekommen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1153703</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1153703</guid><dc:creator><![CDATA[Shade Of Mine]]></dc:creator><pubDate>Thu, 12 Oct 2006 15:06:17 GMT</pubDate></item><item><title><![CDATA[Reply to polsmorphe klasse mit operator=() on Fri, 13 Oct 2006 07:33:29 GMT]]></title><description><![CDATA[<p>Shade Of Mine schrieb:</p>
<blockquote>
<p>wenn du von objekten den gleichen typ verlangst damit sie gleich sind (was wie schon gesagt ob ein problemdarstellt, zB wenn du eine Klasse nur um funktionalitaet, nicht aber um state erweiterst).</p>
<p>ich denke ganz ehrlich, dass dein design irgendwie kaputt ist</p>
<p>mittels typeid() kannst du testen ob der typ von 2 referenzen gleich ist. Damit kannst du dann ein compare mit downcast machen...</p>
<p>aber du wirst damit viele probleme bekommen.</p>
</blockquote>
<p>Das hast du recht. Aber kaputtes Design? Immerhin habe ich eine Forderung an mich gestellt, die ich absolut nicht falsch finde: Ich will einen Container für polymorphe objekte entwerfen, den man per &quot;=&quot; kopieren kann und den man mit &quot;==&quot; vergleichen kann.</p>
<p>Wo liegt in dieser Forderung der Fehler?</p>
<p>Das Kopieren ist schon gut, mit dem Clone(). Mir ist aufgefallen, daß ich, durch die Verwendung von Clone(), nun auch Container im Container verwalten kann, ohne daß ich Probleme bekomme... immerhin kopiere ich die Elemente des Containers nicht durch Zuweisung sondern durch Clonen... und das ist ja virtuell. Damit sind tiefe kopien beliebig verschachtelter Container- und Objekt-Hierarchien möglich, auch von polymorphen. Und diese neue Eigenschaft ist schon sehr wertvoll.</p>
<p>Die Clone Funktion unterstützt mich auch beim Zuweisen von einem Container an einen anderen, denn dadurch ist es möglich, bei &quot;a=b;&quot; die Elemente von a zu löschen und durch Kopien der Elemente von b zu ersetzen.</p>
<p>Der ursprüngliche Gedanke, virtuell zwei beliebige polymorphe Container einander zuzuweisen, ist ziemlich bescheuert. Schließlich ist das ja garnicht sinnvoll möglich, wie schon bemerkt wurde. Um einen polymorphen Container einem anderen zuweisen zu können, müssen sie den selben Typ haben, darum kann ich auch mit gutem Gewissen einen neuen operator=() für jeden abgeleiteten Container-Typ schreiben. Leider habe ich diesen Gedanken mit dem Problem des virtuellen Clones durcheinander gebracht, das durchaus einfach lösbar war (danke!). Der Fähigkeit eines Containers, die Elemente eines anderen Containers zu kopieren, beeinträchtigt das nicht, da ich dafür ausschließlich Clone verwende.</p>
<p>Allerdings: Wenn jemand auf die Idee kommt, zwei abgeleitete Container über einen basiszeiger einander zuzuweisen, dann geht das schief. Ebenso wäre es ein unglück, wenn jemand richtig zuweist (also ohne basiszeiger), aber vergißt, einen operator=() für seine abgleiteten Container zu schreiben. In beiden Fällen würde dann der operator=() des Basis-Containers verwendet, was aber nicht ausreicht, wenn der abgleitete Container eigene Member hat.<br />
Schade nur, daß mir keine vernünftige methode einfällt, um sicherzustellen, daß diese beiden Fehler verhindert werden. Aber damit, daß polymorphe Vererbung etwas kitzlig ist, muß man wohl leben <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=":-/"
      alt="😕"
    /></p>
<p>Letztlich bleibt das Vergleichen von Containern: Dafür habe ich genau auch nur die Lösung gefunden, die dir auch eingefallen ist: typeid() vergleichen. So kann ich ich zwei Container miteinander vergleichen, ohne Rücksicht auf die polymorphie der enthaltenen Elemente nehmen zu müssen. Leider würde ich hier nicht um den downcast herum kommen, in den operator==() Methoden der abgeleiteten Elemente. Denn wenn die Typen gleich sind, soll schließlich noch ein tiefer Vergleich durchgeführt werden. Was ich hiervon halten soll, weiß ich nicht. Aber letztendlich kann man damit wohl schon leben. dynamic_cast ist ja halbwegs sicher, wenn man sich exceptions werfen läßt, falls irgendjemand es doch schafft, zwei verschiedene typen polymorpher objekte zu vergleichen.</p>
<p>Wenn du eine bessere Idee hast, wie man polymorphe Objekthierarchien vergleichen kann, sags mir bitte!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1154002</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1154002</guid><dc:creator><![CDATA[Jordy]]></dc:creator><pubDate>Fri, 13 Oct 2006 07:33:29 GMT</pubDate></item><item><title><![CDATA[Reply to polsmorphe klasse mit operator=() on Fri, 13 Oct 2006 07:53:54 GMT]]></title><description><![CDATA[<p>Was mich noch interessieren würde... wie lösen andere Programmiersprachen das Problem?</p>
<p>Poylmorphe Hierarchien sind doch eigentlich alltäglich. Und trotzdem ist so eine einfach Sache, wie der Vergleich von einer Hierarchie mit einer anderen schon eine große Herausforderung.</p>
<p>Berücksichtigen andere OO Sprachen sowas?</p>
<p>Bin ich der erste, der solche probleme hat?!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1154030</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1154030</guid><dc:creator><![CDATA[Jordy]]></dc:creator><pubDate>Fri, 13 Oct 2006 07:53:54 GMT</pubDate></item><item><title><![CDATA[Reply to polsmorphe klasse mit operator=() on Fri, 13 Oct 2006 08:39:39 GMT]]></title><description><![CDATA[<p>Ich bin eigentlich eher die Sichtweise gewohnt, das ich lauter Basisobjekte habe. Es wird nur mit den Basisobjekten gearbeitet. Nur mit dem, was das Basisobjekt bietet.</p>
<p>Da alle Basisobjekte gleich sind, ist mir nie das Bedürfnis gekommen diese auch zu vergleichen.</p>
<p>In einem Objekt etwas anderes zu sehen als das Basisobjekt unterläuft irgendwie den Sinn der Sache.</p>
<p>Basisobjekt == Basisobjekt, alles andere lässt man virtuelle Methoden erledigen. <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>
]]></description><link>https://www.c-plusplus.net/forum/post/1154067</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1154067</guid><dc:creator><![CDATA[Knuddlbaer]]></dc:creator><pubDate>Fri, 13 Oct 2006 08:39:39 GMT</pubDate></item><item><title><![CDATA[Reply to polsmorphe klasse mit operator=() on Fri, 13 Oct 2006 11:26:26 GMT]]></title><description><![CDATA[<p>Knuddlbaer schrieb:</p>
<blockquote>
<p>Ich bin eigentlich eher die Sichtweise gewohnt, das ich lauter Basisobjekte habe. Es wird nur mit den Basisobjekten gearbeitet. Nur mit dem, was das Basisobjekt bietet.</p>
<p>Da alle Basisobjekte gleich sind, ist mir nie das Bedürfnis gekommen diese auch zu vergleichen.</p>
<p>In einem Objekt etwas anderes zu sehen als das Basisobjekt unterläuft irgendwie den Sinn der Sache.</p>
<p>Basisobjekt == Basisobjekt, alles andere lässt man virtuelle Methoden erledigen. <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>Eine fahrzeugklasse. Davon abgleitet Auto, Schiff, Flugzeug uva. Die Fahrzeuge sind polymorph und haben sehr viele unterschiedliche Eigenschaften.</p>
<p>Du hast zwei Listen, mit Fahrzeugen. Wild gemischt Autos, Schiffe usw.</p>
<p>Ich möchte wissen: Sind die beiden Listen identisch (enthalten sie also die gleichem Fahrzeuge und das in gleicher Reihenfolge?). Dafür brauche ich eine Funktion. Es soll nur true kommen, wenn beide Listen und ihre Fahrzeuge völlig identisch sind.</p>
<p>Wie programmierst du das?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1154079</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1154079</guid><dc:creator><![CDATA[Jordy]]></dc:creator><pubDate>Fri, 13 Oct 2006 11:26:26 GMT</pubDate></item><item><title><![CDATA[Reply to polsmorphe klasse mit operator=() on Fri, 13 Oct 2006 13:00:25 GMT]]></title><description><![CDATA[<p>Erst mal garnicht.</p>
<p>An dem Punkt in dem ich Schiffe Autos Panzer etc. als Fahrzeuge in eine<br />
liste Packe, ist mir der Typ des Objektes egal. Ich hab alles auf Fahrzeuge<br />
reduziert.</p>
<p>Wenn ich die Listen gegeneinander prüfen muss, ob Sie die &gt;&gt;identischen&lt;&lt;<br />
Objekte haben, kann ich dies über das Basisobjekt machen.</p>
<p>Wenn es darum geht ob die &gt;&gt;gleichen&lt;&lt; Fahrzeuge in gleicher Reihenfolge<br />
in zwei unterschiedlichen Listen vorhanden sind, sollte man sich Gedanken<br />
machen warum das so ist, denn es passt nicht in die Polymorphy rein.</p>
<p>Hierzu fällt mir &quot;nur&quot; ein, jedem Objekt eine virtuelle compare Methode zu<br />
verpassen. Wenn nun aber jemand erbt ohne diese Methode neu zu definieren,<br />
wird später eventuell ein LKW für ein Auto gehalten, weil LKW diese Methode<br />
nicht implementiert hat.</p>
<p>Ebenso fehlt mir auf anhieb die Idee, den Typ des zweiten Objektes zu bestimmen.<br />
Alles was mir einfällt wird zu Murks und käme der Idee kaputtes Design sehr nahe.<br />
Lediglich eine virtuelle Methode, die den Typ zurück gibt fänd ich einleuchtend.<br />
Jedoch ergibt sich das Problem, das diese Implementiert sein muss.</p>
<p>IMHO kommt man über die typeID und dem Basiszeiger nicht heran:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;string&gt;

struct A
{
	virtual std::string name(){return &quot;A&quot;;}
};

struct B : public  A
{
	virtual std::string name(){return &quot;B&quot;;}
};
struct C : public  B
{
	virtual std::string name(){return &quot;C&quot;;}
};

struct D: public  A
{
	virtual std::string name(){return &quot;D&quot;;}
};

struct E
{
	virtual std::string name(){return &quot;E&quot;;}
};
struct CE: public E,public C
{
	virtual std::string name(){return &quot;CE&quot;;}
};

int main(int argc, char* argv[])
{
	CE ce;
	C  c;

	CE * ptr_ce = &amp;ce;

	A * ptr = ptr_ce;
	B * ptr2 = ptr_ce;
	C * ptr3 = ptr_ce;
	E * ptr4 = ptr_ce;
	B * ptr5 = &amp;c;

	std::cout&lt;&lt; typeid(ptr_ce).name() &lt;&lt; &quot; ist ein &quot; &lt;&lt; ptr_ce-&gt;name() &lt;&lt;std::endl;
	std::cout&lt;&lt; typeid(ptr).name()  &lt;&lt; &quot; ist ein &quot; &lt;&lt; ptr-&gt;name()&lt;&lt;std::endl;
	std::cout&lt;&lt; typeid(ptr2).name() &lt;&lt; &quot; ist ein &quot; &lt;&lt; ptr2-&gt;name()&lt;&lt;std::endl;
	std::cout&lt;&lt; typeid(ptr3).name() &lt;&lt; &quot; ist ein &quot; &lt;&lt; ptr3-&gt;name()&lt;&lt;std::endl;
	std::cout&lt;&lt; typeid(ptr4).name() &lt;&lt; &quot; ist ein &quot; &lt;&lt; ptr4-&gt;name()&lt;&lt;std::endl;
	std::cout&lt;&lt; typeid(ptr5).name() &lt;&lt; &quot; ist ein &quot; &lt;&lt; ptr5-&gt;name()&lt;&lt;std::endl;

	return 0;
}

// Jup, ich weiß da fehlt nen virt ~ etc.
</code></pre>
<blockquote>
<p>struct CE * ist ein CE<br />
struct A * ist ein CE<br />
struct B * ist ein CE<br />
struct C * ist ein CE<br />
struct E * ist ein CE<br />
struct B * ist ein C</p>
</blockquote>
<p>Mit meinem Wissensstand wird es notwendig jedem Objekt eine Methode zu verpassen,<br />
die Auskunft über den Typ gibt. Je nachdem was mit dem Vergleich der Listen erreicht<br />
werden muss, lässt sich der Vergleich aber ganz umgehen.</p>
<p>So allgemein gehalten fühlt sich die Notwendigkeit einen solchen vergleich machen<br />
zu müssen falsch und riskant an, sobald eine klasse die erbt die implementierung hierfür<br />
nicht bereit stellt , wird es ein falsches Ergebnis liefern. Was soll passieren, wenn<br />
Mehrfachvererbung ins Spiel kommt ? Was wenn ich ein schwimmendes Auto haben will und so<br />
vererbe ?</p>
<pre><code class="language-cpp">struct Fahrzeug
{
	virtual void fahren() = 0;
};

struct Auto : public Fahrzeug
{
	virtual void fahren(){ std::cout&lt;&lt;&quot;brumm&quot;&lt;&lt;std::endl;}
};

struct Schiff : public Fahrzeug
{
	virtual void fahren(){ std::cout&lt;&lt;&quot;blubber&quot;&lt;&lt;std::endl;}
};

struct schwimmendesAuto : public Auto, public Schiff
{
	virtual void fahren(){ Schiff::fahren(); Auto::fahren();}
};

	Fahrzeug * f =  reinterpret_cast&lt;Fahrzeug*&gt;(new schwimmendesAuto);

	f-&gt;fahren();
</code></pre>
<p>Eventuell fehlt mir aber auch KnowHow oder ich habe den Beitrag nicht genau genug gelesen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1154084</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1154084</guid><dc:creator><![CDATA[Knuddlbaer]]></dc:creator><pubDate>Fri, 13 Oct 2006 13:00:25 GMT</pubDate></item><item><title><![CDATA[Reply to polsmorphe klasse mit operator=() on Fri, 13 Oct 2006 13:28:41 GMT]]></title><description><![CDATA[<p>Knuddlbaer schrieb:</p>
<blockquote>
<p>Wenn es darum geht ob die &gt;&gt;gleichen&lt;&lt; Fahrzeuge in gleicher Reihenfolge<br />
in zwei unterschiedlichen Listen vorhanden sind, sollte man sich Gedanken<br />
machen warum das so ist, denn es passt nicht in die Polymorphy rein.</p>
</blockquote>
<p>Ja, es geht um Gleicheit, nicht um Identität.</p>
<p>Und warum passt ein Vergleich zweier Listen nicht in die Polymorphie?</p>
<p>Wie soll man eine Reihe von dynamischen Objekten, die in einer Liste verwaltete werden, sonst vergleichen?!</p>
<p>Ob die Objekte polymorph sind, oder nicht ist doch erstmal egal. Die Polymorphie sollte mir allenfalls *helfen*, ohne ständige Typunterscheidungen mit den Objekten in der Liste zu arbeiten. Sie sollte mir helfen dieses Ziel zu erreichen, *behindern* kann sie es doch kaum!?</p>
<p>Knuddlbaer schrieb:</p>
<blockquote>
<p>Hierzu fällt mir &quot;nur&quot; ein, jedem Objekt eine virtuelle compare Methode zu<br />
verpassen. Wenn nun aber jemand erbt ohne diese Methode neu zu definieren,<br />
wird später eventuell ein LKW für ein Auto gehalten, weil LKW diese Methode<br />
nicht implementiert hat.</p>
</blockquote>
<p>Und genau das ist der Punkt. Das wäre ja genau die Lösung.</p>
<p>Polymorphie entsteht durch virtuelle Funktionen. Ich will also eine virtuelle Compare-methode schreiben (oder eben einen virtuellen operator==()). Die Frage ist aber: Wie? Das problem ist, daß die virtuellen Methoden, die mir einfallen würden, immer ein dynamic_cast benötigen.</p>
<p>Alle sagen mir ich mache einen Design-Fehler. Aber keiner kann mir wirklich erklären *welchen*.</p>
<p>Das beispiel mit den Fahrzeugen in zwei Listen ist doch logisch nachvollziehbar. Solange mir keiner sagt, warum der Wunsch ilegitim sein, zwei solcher Listen zu vergleichen, suche ich nach einer implementation.<br />
Aber dafür hat auch niemand eine Lösung. Soll ich nicht vererben? Soll ich keine Liste mit Basiszeigern verwenden? Soll ich keine Polymorphie verwenden? oder soll ich schlicht dynamic_cast benutzen, ohne schlechtes Gewissen?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1154113</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1154113</guid><dc:creator><![CDATA[Jordy]]></dc:creator><pubDate>Fri, 13 Oct 2006 13:28:41 GMT</pubDate></item><item><title><![CDATA[Reply to polsmorphe klasse mit operator=() on Fri, 13 Oct 2006 13:37:39 GMT]]></title><description><![CDATA[<p>Na, nen Krümel hin werfen und verlangen das jemand den ganzen Vorgang fürs Brotbacken erklärt funktioniert nicht.</p>
<p>Erkläre doch mal &gt;&gt;Warum&lt;&lt; Du diesen Abgleich der Listen benötigst.<br />
Solange Du nicht sagen kannst warum Du den abgleich der Listen brauchst, ist er unnötig. Die Antwort ist wenig Hilfreich aber genauso schön allgemein.</p>
<p>AFAIK gibt es keine Möglichkeit aus einem Basiszeiger die Information herauszubekommen was er denn mal war.</p>
<p>Ich habe bisher nie einen tiefen vergleich benötigt. Ich habe stehts einen Weg über eine virtuelle Methode gewählt.</p>
<p>Wie würde der vergleich denn mit dynamic_cast aussehen ? Vllt. hilft mir das den Horizont zu erweitern und ne Idee zu liefern.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1154122</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1154122</guid><dc:creator><![CDATA[Knuddlbaer]]></dc:creator><pubDate>Fri, 13 Oct 2006 13:37:39 GMT</pubDate></item><item><title><![CDATA[Reply to polsmorphe klasse mit operator=() on Fri, 13 Oct 2006 14:07:23 GMT]]></title><description><![CDATA[<p>Wenn du es wirklich willst, und wie gesagt, ich halte es fuer eher kaputt, kannst du natuerlich die standard variante mit dynamic_cast machen (was anderes geht nicht):</p>
<pre><code class="language-cpp">virtual void compare(Base&amp; o) {
  Derived&amp; other=dynamic_cast&lt;Derived&amp;&gt;(other);
  return this.foo == other.foo;
}
</code></pre>
<p>aber an Bloch denken, der in effective Java schreibt:</p>
<blockquote>
<p>There is simply no way to<br />
extend an instantiable class and add an aspect while preserving the equals<br />
contract.</p>
</blockquote>
<p>und equals bezieht sich hier auf unsere compare methode.</p>
<p>solche vergleiche mit nicht-value klassen sind oft ein problem. es macht idR auch keinen sinn solche vergleiche zu verlangen...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1154140</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1154140</guid><dc:creator><![CDATA[Shade Of Mine]]></dc:creator><pubDate>Fri, 13 Oct 2006 14:07:23 GMT</pubDate></item><item><title><![CDATA[Reply to polsmorphe klasse mit operator=() on Fri, 13 Oct 2006 14:25:40 GMT]]></title><description><![CDATA[<p>Ok, auch wenn ich nix zu beitragen konnte, hat mir der Beitrag was gebracht <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>thx @ Shade</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1154158</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1154158</guid><dc:creator><![CDATA[Knuddlbaer]]></dc:creator><pubDate>Fri, 13 Oct 2006 14:25:40 GMT</pubDate></item><item><title><![CDATA[Reply to polsmorphe klasse mit operator=() on Fri, 13 Oct 2006 14:52:49 GMT]]></title><description><![CDATA[<p>Knuddlbaer schrieb:</p>
<blockquote>
<p>Da alle Basisobjekte gleich sind, ist mir nie das Bedürfnis gekommen diese auch zu vergleichen.</p>
<p>In einem Objekt etwas anderes zu sehen als das Basisobjekt unterläuft irgendwie den Sinn der Sache.</p>
<p>Basisobjekt == Basisobjekt, alles andere lässt man virtuelle Methoden erledigen. <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>Die Argumentation kann ich nicht nachvollziehen. Wieso sind alle Basisobjekte gleich? Sind dann auch alle ints gleich? int==int und ints vergleichen macht keinen Sinn?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1154186</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1154186</guid><dc:creator><![CDATA[Jester]]></dc:creator><pubDate>Fri, 13 Oct 2006 14:52:49 GMT</pubDate></item><item><title><![CDATA[Reply to polsmorphe klasse mit operator=() on Fri, 13 Oct 2006 15:00:07 GMT]]></title><description><![CDATA[<p>Weil ein Basisobjekt ein Basisobjekt ist ?</p>
<p>Also ein Fahrzeug ein Fahrzeug und kein Schiff Panzer oder sonst was ?!</p>
<p>Ich kann ein Basisobjekt mit einem Basisobjekt vergleichen wie ein int mit einem int. Ich kann aber kein std::string mit einem int vergleichen wie ich kein schiff mit einem panzer vergleichen kann.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1154193</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1154193</guid><dc:creator><![CDATA[Knuddlbaer]]></dc:creator><pubDate>Fri, 13 Oct 2006 15:00:07 GMT</pubDate></item><item><title><![CDATA[Reply to polsmorphe klasse mit operator=() on Fri, 13 Oct 2006 23:27:24 GMT]]></title><description><![CDATA[<p>Vielleicht würden sich alle leichter tun wenn du statt Autos und Booten mal konkret schreibst um was es geht (oder hab ich das überlesen?).<br />
Ansonsten sehe ich das Problem nicht. Die Lösung heisst typeid. Guckst du:</p>
<pre><code class="language-cpp">#include &lt;cassert&gt;
#include &lt;string&gt;
#include &lt;memory&gt;
#include &lt;iostream&gt;

class Vehicle
{
public:
	Vehicle(int maxSpeed)
		:	m_maxSpeed(maxSpeed)
	{
	}

	bool operator == (Vehicle const&amp; other) const // final
	{
		// virtual call to CompareImpl of whatever class (*this) is
		return CompareImpl(other);
	}

	bool operator != (Vehicle const&amp; other) const // final
	{
		// virtual call to CompareImpl of whatever class (*this) is
		return !CompareImpl(other);
	}

	// virtual interface:
	virtual std::string Foo()
	{
		return &quot;Vehicle&quot;;
	}

protected:
	// compare the Vehicle part of 2 Vehicles
	bool CompareVehicles(Vehicle const&amp; other) const
	{
		return m_maxSpeed == other.m_maxSpeed;
	}

private:
	// only ever called by operators == and != of Vehicle
	// override in every derived class
	virtual bool CompareImpl(Vehicle const&amp; other) const
	{
		assert(typeid(*this) == typeid(Vehicle)); // (*this) MUST be a Vehicle (and NO derived class)
		if(typeid(other) == typeid(Vehicle))
			return CompareVehicles(other);
		else
			return false;
	}

	int m_maxSpeed;
};

class Car
	:	public Vehicle
{
public:
	Car(int maxSpeed, int wheelCount)
		:	Vehicle(maxSpeed),
			m_wheelCount(wheelCount)
	{
	}

	// virtual interface:
	virtual std::string Foo()
	{
		return &quot;Car&quot;;
	}

protected:
	// compare the Car part of 2 Cars
	bool CompareCars(Car const&amp; other) const
	{
		return CompareVehicles(other) &amp;&amp; (m_wheelCount == other.m_wheelCount);
	}

private:
	// see Vehicle::CompareImpl
	virtual bool CompareImpl(Vehicle const&amp; other) const
	{
		assert(typeid(*this) == typeid(Car)); // (*this) MUST be a Car (and NO derived class)
		if(typeid(other) == typeid(Car))
			// since we now know the exact type of (other) we don't need a slow dynamic_cast
			return CompareCars(static_cast&lt;Car const&amp;&gt;(other));
		else
			return false;
	}

	int m_wheelCount;
};

class Boat
	:	public Vehicle
{
public:
	Boat(int maxSpeed, int draught)
		:	Vehicle(maxSpeed),
			m_draught(draught)
	{
	}

	// virtual interface:
	virtual std::string Foo()
	{
		return &quot;Boat&quot;;
	}

protected:
	bool compareBoats(Boat const&amp; other) const
	{
		return CompareVehicles(other) &amp;&amp; (m_draught == other.m_draught);
	}

private:
	// see Vehicle::CompareImpl
	virtual bool CompareImpl(Vehicle const&amp; other) const
	{
		assert(typeid(*this) == typeid(Boat)); // (*this) MUST be a Boat (and NO derived class)
		if(typeid(other) == typeid(Boat))
			// since we now know the exact type of (other) we don't need a slow dynamic_cast
			return compareBoats(static_cast&lt;Boat const&amp;&gt;(other));
		else
			return false;
	}

	int m_draught;
};

int main(int argc, char** argv)
{
	std::auto_ptr&lt;Vehicle&gt; vehicle(new Vehicle(10));
	std::auto_ptr&lt;Vehicle&gt; car1(new Car(10, 4));
	std::auto_ptr&lt;Vehicle&gt; car2(new Car(10, 4));
	std::auto_ptr&lt;Vehicle&gt; car3(new Car(10, 6));
	std::auto_ptr&lt;Vehicle&gt; boat1(new Boat(10, 4));
	std::auto_ptr&lt;Vehicle&gt; boat2(new Boat(10, 4));
	std::auto_ptr&lt;Vehicle&gt; boat3(new Boat(10, 99));

	assert(*vehicle == *vehicle);
	assert(*car1 != *vehicle);
	assert(*boat1 != *vehicle);
	assert(*car1 == *car2);
	assert(*car1 != *car3);
	assert(*car2 != *car3);
	assert(*boat1 == *boat2);
	assert(*boat1 != *boat3);
	assert(*boat2 != *boat3);

	assert(*car1 != *boat1);
	assert(*car2 != *boat1);
	//...

	std::cout &lt;&lt; &quot;Vehicle: &quot; &lt;&lt; vehicle-&gt;Foo() &lt;&lt; std::endl;
	std::cout &lt;&lt; &quot;Car: &quot; &lt;&lt; car1-&gt;Foo() &lt;&lt; std::endl;
	std::cout &lt;&lt; &quot;Boat: &quot; &lt;&lt; boat1-&gt;Foo() &lt;&lt; std::endl;
	std::cout &lt;&lt; std::flush;

	return 0;
}
</code></pre>
<p>Funktioniert wunderbar. Und typeid(a) == typeid(b) würde ich immer einem dynamic_cast vorziehen, ganz einfach weil es schneller ist, und weil du mit dynamic_cast einen doofen Tanz aufführen musst um draufzukommen ob denn das zu testende Objekt wirklich ein &quot;Bar&quot; ist oder nur ein von &quot;Bar&quot; abgeleitetes etwas. Gehen tut es schon, sieht dann aber so aus (*würg*):</p>
<pre><code class="language-cpp">Vehicle* v = GimmeSomeVehicle();
	// see if v is a car (and NOT an instance of a derived type)
	if((dynamic_cast&lt;Car*&gt;(v) != 0) &amp;&amp; (dynamic_cast&lt;void*&gt;(v) == static_cast&lt;Car*&gt;(v)))
		DoSomethingWithCar(static_cast&lt;Car*&gt;(v));
</code></pre>
<p>Erklärung: dynamic_cast&lt;void*&gt; gibt die Adresse des &quot;most derived type&quot; zurück. Wenn diese gleich der Adresse von &quot;v auf Car gecastet&quot; ist, dann muss v ein Car sein und kein von Car abgeleiteter Typ. Da wir aber nicht einfach v auf Car* casten können ohne überhaupt zu wissen ob v ein Car oder von Car abgeleiteter Typ ist müssen wir das vorher nochmal prüfen, daher der Test (dynamic_cast&lt;Car*&gt;(v) != 0).</p>
<p>Wie gesagt alles viel zu kompliziert, von daher lieber typeid verwenden.</p>
<p>Falls die Objekte um die es geht serialisierung unterstützen ist es überhaupt recht einfach, denn dann musst du bloss die serialisierten Daten vergleichen. In den serialisierten Daten muss ja wohl eine Art eindeutiger Typenkennung vorkommen, sonst kannst du sie ja nie mehr deserialisieren.</p>
<p>Ahja, das Zuweisen... . Entweder du klonst wirklich die Objekte anstatt Zuweisungn zu verwenden (dann musst du eben damit leben das Alte wegzuwerfen und ein Neues zu machen), oder aber du wirst auf das Problem stossen dass du die Zuweisung &quot;DerivedType = BaseType;&quot; irgendwie behandeln musst. Entweder man verbietet es und du wirfst einen std::logic_error, oder aber du musst den DerivedType mit irgendwelchen Defaultwerten füttern. Auch doof. Lässt sich aber auf jeden Fall gleich wie die Operatoren == und != oben umsetzen.</p>
<p>Im übrigen gehe ich auch davon aus dass es ein eleganteres Design geben müsste. Kann ich aber nicht sagen solange du nicht sagst worum es konkret geht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1154417</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1154417</guid><dc:creator><![CDATA[Plotzenhotz]]></dc:creator><pubDate>Fri, 13 Oct 2006 23:27:24 GMT</pubDate></item></channel></rss>