<?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[dynamic_cast testen]]></title><description><![CDATA[<p>Hallo,</p>
<p>bei einem alten Compiler möchte ich in Zukunft auch RTTI, vor allem aber den dynamic_cast verwenden.</p>
<p>Bisher war RTTI im Projekt deaktiviert, das SW Design ist aber höchst polymorph gehalten, ständig sieht man so tolle Casts wie:</p>
<pre><code>Basis *b=ListeVonPolymorphenObjekten[x];
if(b-&gt;GetTyp()==eTypA)
{
 Abgeleitet *a=static_cast&lt;Abgeleitet*&gt;(b);
 a-&gt;EineFunktionVonAbgeleitet(); // bummm!
}
</code></pre>
<p>Durch Änderungen im Code ist es öfter als einmal vorgekommen, dass mit dem static_cast auf die falsche Klasse konvertiert worden ist, dann wurde eine Funktion aufgerufen, die es natürlich garnicht gibt (weil falscher Typ), und bumm, Absturz.</p>
<p>In Zukunft möchte ich zumindest in neuen Codeteilen so arbeiten, dass ich nur mit dynamic_cast von der Basis auf eine abgeleitete Klasse caste.<br />
Dann hab ich wenigstens die Garantie, dass ich auch tatsächlich mit dem richtigen Typen arbeite.</p>
<pre><code>Basis *b=ListeVonPolymorphenObjekten[x];
Abgeleitet *a=dynamic_cast&lt;Abgeleitet*&gt;(b);

if(a)
{
 a-&gt;EineFunktionVonAbgeleitet(); 
}
</code></pre>
<p>Wie erwähnt, der Compiler ist alt und setzt den C++ Standard teilweise falsch um. Trotzdem müssen wir mit diesem Compiler kompatibel bleiben.<br />
Wie kann ich nun den Compiler auf Herz und Nieren testen, dass er mir den dynamic_cast auch korrekt durchführt?</p>
<p>Ich hab mir sowas in der Art vorgestellt.<br />
Zur Erklärung: /GR bedeutet RTTI aktivieren, /GR- dekativieren. Die stopHere hab ich mir hingesetzt, damit ich Breakpoints setzen kann.</p>
<p>Reicht der Test, oder fehlen noch irgendwelche Spezialfälle, um zu sehen, ob dynamic_cast funktioniert?</p>
<pre><code>// Klassen Hierachie:
//    A
//  /   \
// B      C
// |
// D

struct A
{
	virtual char GetType()
	{
		return 'A';
	}
};

struct B : public A
{
	virtual char GetType()
	{
		return 'B';
	}
};

struct C : public A
{
	virtual char GetType()
	{
		return 'C';
	}
};

struct D : public B
{
	virtual char GetType()
	{
		return 'D';
	}
};

void testRTTI()
{
	A *pA=0, *pB, *pC, *pD;
	pA=new A;
	pB=new B;
	pC=new C;
	pD=new D;

	// pA auf B* konvertieren =&gt; erwartet: else
	// Ergebnis mit /GR:
	// Ergebnis mit /GR-:
	if(dynamic_cast&lt;B*&gt;(pA))
	{
		int stopHere=0;
	}
	else
	{
		int stopHere=0;
	}

	// pB auf B* konvertieren =&gt; erwartet: if
	// Ergebnis mit /GR:
	// Ergebnis mit /GR-:
	if(dynamic_cast&lt;B*&gt;(pB))
	{
		int stopHere=0;
	}
	else
	{
		int stopHere=0;
	}

	// pC auf B* konvertieren =&gt; erwartet: else
	// Ergebnis mit /GR:
	// Ergebnis mit /GR-:
	if(dynamic_cast&lt;B*&gt;(pC))
	{
		int stopHere=0;
	}
	else
	{
		int stopHere=0;
	}

	// pD auf B* konvertieren =&gt; erwartet: if
	// Ergebnis mit /GR:
	// Ergebnis mit /GR-:
	if(dynamic_cast&lt;B*&gt;(pD))
	{
		int stopHere=0;
	}
	else
	{
		int stopHere=0;
	}
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/317344/dynamic_cast-testen</link><generator>RSS for Node</generator><lastBuildDate>Tue, 28 Jul 2026 23:07:06 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/317344.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 05 Jun 2013 14:26:30 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to dynamic_cast testen on Wed, 05 Jun 2013 14:26:30 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>bei einem alten Compiler möchte ich in Zukunft auch RTTI, vor allem aber den dynamic_cast verwenden.</p>
<p>Bisher war RTTI im Projekt deaktiviert, das SW Design ist aber höchst polymorph gehalten, ständig sieht man so tolle Casts wie:</p>
<pre><code>Basis *b=ListeVonPolymorphenObjekten[x];
if(b-&gt;GetTyp()==eTypA)
{
 Abgeleitet *a=static_cast&lt;Abgeleitet*&gt;(b);
 a-&gt;EineFunktionVonAbgeleitet(); // bummm!
}
</code></pre>
<p>Durch Änderungen im Code ist es öfter als einmal vorgekommen, dass mit dem static_cast auf die falsche Klasse konvertiert worden ist, dann wurde eine Funktion aufgerufen, die es natürlich garnicht gibt (weil falscher Typ), und bumm, Absturz.</p>
<p>In Zukunft möchte ich zumindest in neuen Codeteilen so arbeiten, dass ich nur mit dynamic_cast von der Basis auf eine abgeleitete Klasse caste.<br />
Dann hab ich wenigstens die Garantie, dass ich auch tatsächlich mit dem richtigen Typen arbeite.</p>
<pre><code>Basis *b=ListeVonPolymorphenObjekten[x];
Abgeleitet *a=dynamic_cast&lt;Abgeleitet*&gt;(b);

if(a)
{
 a-&gt;EineFunktionVonAbgeleitet(); 
}
</code></pre>
<p>Wie erwähnt, der Compiler ist alt und setzt den C++ Standard teilweise falsch um. Trotzdem müssen wir mit diesem Compiler kompatibel bleiben.<br />
Wie kann ich nun den Compiler auf Herz und Nieren testen, dass er mir den dynamic_cast auch korrekt durchführt?</p>
<p>Ich hab mir sowas in der Art vorgestellt.<br />
Zur Erklärung: /GR bedeutet RTTI aktivieren, /GR- dekativieren. Die stopHere hab ich mir hingesetzt, damit ich Breakpoints setzen kann.</p>
<p>Reicht der Test, oder fehlen noch irgendwelche Spezialfälle, um zu sehen, ob dynamic_cast funktioniert?</p>
<pre><code>// Klassen Hierachie:
//    A
//  /   \
// B      C
// |
// D

struct A
{
	virtual char GetType()
	{
		return 'A';
	}
};

struct B : public A
{
	virtual char GetType()
	{
		return 'B';
	}
};

struct C : public A
{
	virtual char GetType()
	{
		return 'C';
	}
};

struct D : public B
{
	virtual char GetType()
	{
		return 'D';
	}
};

void testRTTI()
{
	A *pA=0, *pB, *pC, *pD;
	pA=new A;
	pB=new B;
	pC=new C;
	pD=new D;

	// pA auf B* konvertieren =&gt; erwartet: else
	// Ergebnis mit /GR:
	// Ergebnis mit /GR-:
	if(dynamic_cast&lt;B*&gt;(pA))
	{
		int stopHere=0;
	}
	else
	{
		int stopHere=0;
	}

	// pB auf B* konvertieren =&gt; erwartet: if
	// Ergebnis mit /GR:
	// Ergebnis mit /GR-:
	if(dynamic_cast&lt;B*&gt;(pB))
	{
		int stopHere=0;
	}
	else
	{
		int stopHere=0;
	}

	// pC auf B* konvertieren =&gt; erwartet: else
	// Ergebnis mit /GR:
	// Ergebnis mit /GR-:
	if(dynamic_cast&lt;B*&gt;(pC))
	{
		int stopHere=0;
	}
	else
	{
		int stopHere=0;
	}

	// pD auf B* konvertieren =&gt; erwartet: if
	// Ergebnis mit /GR:
	// Ergebnis mit /GR-:
	if(dynamic_cast&lt;B*&gt;(pD))
	{
		int stopHere=0;
	}
	else
	{
		int stopHere=0;
	}
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2328818</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2328818</guid><dc:creator><![CDATA[rttiTester]]></dc:creator><pubDate>Wed, 05 Jun 2013 14:26:30 GMT</pubDate></item><item><title><![CDATA[Reply to dynamic_cast testen on Wed, 05 Jun 2013 14:37:49 GMT]]></title><description><![CDATA[<p>rttiTester schrieb:</p>
<blockquote>
<p>Durch Änderungen im Code ist es öfter als einmal vorgekommen, dass mit dem static_cast auf die falsche Klasse konvertiert worden ist</p>
</blockquote>
<p>dynamic_cast ist hier der falsche Ansatz. Das kostet nur Performance (und nicht zu knapp!!)</p>
<p>Sofern dein alter Compiler Templates unterstützt:</p>
<pre><code class="language-cpp">template &lt;typename T&gt; T* basis_cast(Basis *b) {
  assert(b-&gt;getType() == T::eTypA); // check
  return static_cast&lt;T*&gt;(b); // safe
}

// das kann nicht mehr schiefgehen
Basis *b=ListeVonPolymorphenObjekten[x];
if(b-&gt;GetTyp()==eTypA)
{
 Abgeleitet *a=basis_cast&lt;Abgeleitet*&gt;(b); // bummm schon hier!
 a-&gt;EineFunktionVonAbgeleitet();
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2328820</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2328820</guid><dc:creator><![CDATA[auchabgeleitet]]></dc:creator><pubDate>Wed, 05 Jun 2013 14:37:49 GMT</pubDate></item><item><title><![CDATA[Reply to dynamic_cast testen on Wed, 05 Jun 2013 14:49:37 GMT]]></title><description><![CDATA[<p>Mal eine vielleicht etwas naive Frage: ist so etwas wie</p>
<pre><code>b-&gt;GetTyp()
</code></pre>
<p>nicht bereits so etwas wie RTTI, nur eben selbstgebastelt? Wie sind &quot;echte&quot; RTTI üblicherweise Implementiert und warum ist das langsamer?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2328822</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2328822</guid><dc:creator><![CDATA[TNA]]></dc:creator><pubDate>Wed, 05 Jun 2013 14:49:37 GMT</pubDate></item><item><title><![CDATA[Reply to dynamic_cast testen on Wed, 05 Jun 2013 14:58:18 GMT]]></title><description><![CDATA[<p>TNA schrieb:</p>
<blockquote>
<p>Wie sind &quot;echte&quot; RTTI üblicherweise Implementiert</p>
</blockquote>
<p>Stringvergleiche und Baumtraversierung.</p>
<blockquote>
<p>und warum ist das langsamer?</p>
</blockquote>
<p>Weil das offensichtlich langsam ist.<br />
Libraryübergreifend geht das nicht viel besser.</p>
<blockquote>
<p>RTTI, nur eben selbstgebastelt?</p>
</blockquote>
<p>Es bieten sich Primzahlen an.</p>
<pre><code>A=(2,2)
   /        \
B=(3,6)     C=(5,10)
  |
D=(7,30)
</code></pre>
<p>Die erste Zahl ist eine eindeutige Primzahl, die zweite Zahl ist das Produkt der Basisklassen.</p>
<p>Teilbarkeit ist damit Teilbarkeit Variable.getID()%Klasse::primzahl == 0 =&gt; Variable ist vom Typ Klasse.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2328824</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2328824</guid><dc:creator><![CDATA[auchabgeleitet]]></dc:creator><pubDate>Wed, 05 Jun 2013 14:58:18 GMT</pubDate></item><item><title><![CDATA[Reply to dynamic_cast testen on Wed, 05 Jun 2013 15:00:14 GMT]]></title><description><![CDATA[<p>@auchabgeleitet: assert meldet sich nur im Debug Modus. Die Lösung muss auch beim Kunden funktionieren, da die Sache einigermaßen komplex ist, können durchaus Konstellationen auftreten, die wir im Test nicht nachstellen konnten, und dynamic_cast mag zwar langsam sein, aber wenigstens ist es sicher.</p>
<p>Mal abgesehen davon hätte dynamic_cast ja auch den Vorteil, dass sowohl ein B als auch ein D auf B konvertiert wird.<br />
Mit dem von dir vorgeschlagenen Typvergleich erschlage ich nur den Fall, dass es sich tatsächlich um ein B handelt.</p>
<p>A* pB=new B;<br />
A* pD=new D;</p>
<p>dynamic_cast wandelt mir beide in ein B* um, während dein basis_cast ja nur bei pB, nicht aber bei pD funktioniert.</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/30768">@TNA</a>: dynamic_cast durchwandert ganze Klassenhierachien, um zu sehen, ob der Cast ok ist. Klar ist GetType() auch eine Art von RTTI, aber dynamic_cast kann mehr.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2328826</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2328826</guid><dc:creator><![CDATA[rttiTester]]></dc:creator><pubDate>Wed, 05 Jun 2013 15:00:14 GMT</pubDate></item><item><title><![CDATA[Reply to dynamic_cast testen on Wed, 05 Jun 2013 15:06:41 GMT]]></title><description><![CDATA[<p>rttiTester schrieb:</p>
<blockquote>
<p>@auchabgeleitet: assert meldet sich nur im Debug Modus. Die Lösung muss auch beim Kunden funktionieren, da die Sache einigermaßen komplex ist, können durchaus Konstellationen auftreten, die wir im Test nicht nachstellen konnten, und dynamic_cast mag zwar langsam sein, aber wenigstens ist es sicher.</p>
</blockquote>
<p>Es steht dir natürlich auch frei, das assert durch ein <code>throw InvalidClassCastExecutorManagerException()</code> zu ersetzen.</p>
<p>rttiTester schrieb:</p>
<blockquote>
<p>Mal abgesehen davon hätte dynamic_cast ja auch den Vorteil, dass sowohl ein B als auch ein D auf B konvertiert wird.</p>
</blockquote>
<p>Wie habt ihr das dann bisher gemacht!?</p>
<p>Ansonsten halt <code>basis_cast</code> spezialisieren (tag-dispatchen) um für jede Klasse einen eigenen Casting-Code zu schreiben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2328830</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2328830</guid><dc:creator><![CDATA[auchabgeleitet]]></dc:creator><pubDate>Wed, 05 Jun 2013 15:06:41 GMT</pubDate></item><item><title><![CDATA[Reply to dynamic_cast testen on Wed, 05 Jun 2013 15:09:21 GMT]]></title><description><![CDATA[<p>auchabgeleitet schrieb:</p>
<blockquote>
<p>rttiTester schrieb:</p>
<blockquote>
<p>Durch Änderungen im Code ist es öfter als einmal vorgekommen, dass mit dem static_cast auf die falsche Klasse konvertiert worden ist</p>
</blockquote>
<p>dynamic_cast ist hier der falsche Ansatz. Das kostet nur Performance (und nicht zu knapp!!)</p>
</blockquote>
<p>Das ist mal wieder so ein &quot;premature optimization&quot;. Es kommt immer darauf an, ob das wirklich relevant ist. Sicher ist dynamic_cast nicht die schnellste Möglichkeit, aber vielleicht an der Stelle die übersichtlichste und robusteste Variante. Da fallen ein paar CPU-Zyklen dann wirklich nicht ins Gewicht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2328831</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2328831</guid><dc:creator><![CDATA[tntnet]]></dc:creator><pubDate>Wed, 05 Jun 2013 15:09:21 GMT</pubDate></item><item><title><![CDATA[Reply to dynamic_cast testen on Wed, 05 Jun 2013 15:13:53 GMT]]></title><description><![CDATA[<p>Meistens will man <code>static_cast</code> für Downcasts. Und <code>dynamic_cast</code> wird dann höchstens zur Kontrolle im Debug-Modus verwendet. Du kannst das auch kombinieren, wie <code>boost::polymorphic_downcast</code> .</p>
<p>Mit <code>if</code> und <code>dynamic_cast</code> verbirgst du nur Logikfehler. Du gehst davon aus, dass sich eine Klasse downcasten lässt, wie reagierst du bei falschen Typen? Du kannst nicht reagieren. Das einzig Richtige hier ist ein <code>assert()</code> o.Ä., sodass dieser Fall sicher nicht durch den Debugger kommt. Einfach eine <code>if</code> -Abfrage und nichts tun, bedeutet Logikfehler ignorieren und Applikation in korruptem Status weiterlaufen lassen.</p>
<p>auchabgeleitet schrieb:</p>
<blockquote>
<p>Weil das offensichtlich langsam ist.<br />
Libraryübergreifend geht das nicht viel besser.</p>
</blockquote>
<p>Warum ist <code>typeid</code> langsamer als <code>getType()</code> ?</p>
<p>auchabgeleitet schrieb:</p>
<blockquote>
<p>Es steht dir natürlich auch frei, das assert durch ein <code>throw InvalidClassCastExecutorManagerException()</code> zu ersetzen.</p>
</blockquote>
<p><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>tntnet schrieb:</p>
<blockquote>
<p>Sicher ist dynamic_cast nicht die schnellste Möglichkeit, aber vielleicht an der Stelle die übersichtlichste und robusteste Variante. Da fallen ein paar CPU-Zyklen dann wirklich nicht ins Gewicht.</p>
</blockquote>
<p>Du weisst ja nicht, wie oft die Downcasts vorkommen, <code>dynamic_cast</code> kann schon ins Gewicht fallen. Vor allem wenn man bedenkt, dass der Overhead bei korrektem Code nicht nötig ist. Wie gesagt ist schon der Ansatz, <code>dynamic_cast</code> hier verwenden zu wollen, verkehrt -- Performance ist dabei nebensächlich.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2328834</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2328834</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Wed, 05 Jun 2013 15:13:53 GMT</pubDate></item><item><title><![CDATA[Reply to dynamic_cast testen on Wed, 05 Jun 2013 15:20:34 GMT]]></title><description><![CDATA[<p>tntnet schrieb:</p>
<blockquote>
<p>Sicher ist dynamic_cast nicht die schnellste Möglichkeit, aber vielleicht an der Stelle die übersichtlichste und robusteste Variante.</p>
</blockquote>
<p>Stimmt, ich so gewohnt, dass GetType() nur an performance-kritischen Stellen vorkommt, dass ich stillschweigend davon ausgegangen bin.</p>
<p>Übersichtliche und robuste Alternativen sind virtuelle Funktionen im Objekt oder das Visitor-Pattern.</p>
<p>Nexus schrieb:</p>
<blockquote>
<p>Warum ist <code>typeid</code> langsamer als <code>getType()</code> ?</p>
</blockquote>
<p>Der Test, ob A von B erbt ist ungefähr so implementiert:</p>
<pre><code class="language-cpp">for (auto a_type = typeid(A); a_type.name() != typeid(B).name();) {
//                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-- das ist richtig lahm
  if (a_type.has_parent())
    a_type = a_type.parent();
  else
    return false;
}
return true;
</code></pre>
<p>Jetzt vergleich das mal mit einem einfachen Funktionspointeraufruf.</p>
<p>Ich gehe sogar so weit und habe ein Feld mit der ID. Dann ist das nicht mal ein Funktionsaufruf.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2328837</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2328837</guid><dc:creator><![CDATA[auchabgeleitet]]></dc:creator><pubDate>Wed, 05 Jun 2013 15:20:34 GMT</pubDate></item><item><title><![CDATA[Reply to dynamic_cast testen on Wed, 05 Jun 2013 15:23:43 GMT]]></title><description><![CDATA[<p>Korrigierte version:</p>
<pre><code class="language-cpp">bool a_erbt_von_b(type_info a_type, type_info b_type) {
  if (a_type.name() == b_type.name();
    return true;
  for (type_info p : a_type.parents())
   if (a_erbt_von_b(p, b))
      return true;
  return false;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2328838</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2328838</guid><dc:creator><![CDATA[auchabgeleitet]]></dc:creator><pubDate>Wed, 05 Jun 2013 15:23:43 GMT</pubDate></item><item><title><![CDATA[Reply to dynamic_cast testen on Wed, 05 Jun 2013 15:50:49 GMT]]></title><description><![CDATA[<p>ok, um es kurz zu sagen:<br />
klar wäre es mir auch lieber, wenn das design dementsprechend wäre, dass man ohne typinfos auskommt.<br />
ist aber nicht so.<br />
und ich kann mich auch nicht 100% darauf verlassen, dass ich immer die richtigen typen übergeben bekomme. auch nicht schön.<br />
ist aber so.<br />
ich brauche jetzt erstmal eine robuste methode, um sichere downcasts durchzuführen. und dafür ist dynamic_cast geeignet.</p>
<p>also bitte keine bekehrungen im sinne von &quot;dynamic_cast ist ungeeignet&quot;. ich werde es im ersten schritt verwenden müssen. mir ist es lieber, wenn die SW beim kunden etwas langsamer ist, als wenn es kracht.</p>
<p>also daher nochmals meine ursprüngliche frage, auf die bis jetzt keine antwort kam: welche tests sind nötig, um zu sehen, ob dynamic_cast einwandfrei funktioniert? was wären &quot;härtefälle&quot;? reicht der test, den ich oben präsentiert habe?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2328845</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2328845</guid><dc:creator><![CDATA[rttiTester]]></dc:creator><pubDate>Wed, 05 Jun 2013 15:50:49 GMT</pubDate></item><item><title><![CDATA[Reply to dynamic_cast testen on Wed, 05 Jun 2013 16:32:39 GMT]]></title><description><![CDATA[<p>Ich verstehe immer noch nicht, warum <code>GetTyp()</code> besser als <code>typeid</code> sein sollte. Ich wuerde naemlich den Typ in der vtable hinterlegen oder aehnlich.</p>
<p>Weiterhin funktioniert die vorgestellte Loesung nur mit Blaettern in der Vererbungshierarchie. dynamic_cast beruecksichtigt auch Zwischenknoten. Deswegen wird wohl dynamic_cast auch langsamer sein als GetType/typeid, aber beide Ansaetze sind sowieso nicht aequivalent.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2328846</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2328846</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Wed, 05 Jun 2013 16:32:39 GMT</pubDate></item><item><title><![CDATA[Reply to dynamic_cast testen on Wed, 05 Jun 2013 16:23:51 GMT]]></title><description><![CDATA[<p>auchabgeleitet schrieb:</p>
<blockquote>
<p>Der Test, ob A von B erbt ist ungefähr so implementiert:</p>
</blockquote>
<p>warum sollte es das sein? dr COmpiler kann doch einfach einen Baum speichern der Pro Typ ienen Knoten hat und dann pro Instanz die ID des passenden Klassenknoten speichern. mit der id findest du dann den passenden Knoten im Baum und upcasten ist dann einfach nur die parents solange traversieren bis in Knoten die richtige ID hat. crosscast ist dann Breitensuche im Baum.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2328847</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2328847</guid><dc:creator><![CDATA[otze]]></dc:creator><pubDate>Wed, 05 Jun 2013 16:23:51 GMT</pubDate></item><item><title><![CDATA[Reply to dynamic_cast testen on Wed, 05 Jun 2013 17:23:31 GMT]]></title><description><![CDATA[<p>knivil schrieb:</p>
<blockquote>
<p>Weiterhin funktioniert die vorgestellte Loesung nur mit Blaettern in der Vererbungshierarchie. dynamic_cast beruecksichtigt auch Zwischenknoten.</p>
</blockquote>
<p>und Mehrdeutigkeiten. Die Suche kann also bei einem Fund nicht sofort abgebrochen werden. Die Laufzeit eines cross-Casts hängt damit wesentlich von der Gesamtgröße der Vererbungshierarchie ab.<br />
Einfache Downcasts gehen nat. schneller. Was nicht hilft, wenn der Cast fehlschlägt (dann musste ja der Algorithmus für den Crosscast erst mal angewendet werden).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2328853</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2328853</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Wed, 05 Jun 2013 17:23:31 GMT</pubDate></item><item><title><![CDATA[Reply to dynamic_cast testen on Wed, 05 Jun 2013 17:57:36 GMT]]></title><description><![CDATA[<blockquote>
<pre><code>a_type.name() != typeid(B).name()
</code></pre>
</blockquote>
<p>Meine Güte, liest hier keiner Alexandrescu? <strong>Das funktioniert nicht!</strong> Es ist nicht garantiert dass zwei Klassen unterschiedliche &quot; <code>type_info</code> &quot;-Namen haben, und auch nicht dass der Name überhaupt gleich bleibt (in der anderen Implementierung oder auch Version)!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2328858</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2328858</guid><dc:creator><![CDATA[Sone]]></dc:creator><pubDate>Wed, 05 Jun 2013 17:57:36 GMT</pubDate></item><item><title><![CDATA[Reply to dynamic_cast testen on Wed, 05 Jun 2013 18:18:04 GMT]]></title><description><![CDATA[<p>Deswegen nimmt man ja auch nicht den String sondern die Id. Stringvergleiche sind unnoetig.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2328862</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2328862</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Wed, 05 Jun 2013 18:18:04 GMT</pubDate></item><item><title><![CDATA[Reply to dynamic_cast testen on Wed, 05 Jun 2013 18:38:45 GMT]]></title><description><![CDATA[<p>Sone schrieb:</p>
<blockquote>
<blockquote>
<pre><code>a_type.name() != typeid(B).name()
</code></pre>
</blockquote>
<p>Meine Güte, liest hier keiner Alexandrescu?</p>
</blockquote>
<p>Viel zu viele Leute lesen Alexandrescu.</p>
<p>Dir ist schon bewusst, dass das eine Beispielimplementation für dynamic_cast war? Die Compilerhersteller werden schon wsisen, ob sie kompatibel zu sich selbst sind.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2328864</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2328864</guid><dc:creator><![CDATA[otze]]></dc:creator><pubDate>Wed, 05 Jun 2013 18:38:45 GMT</pubDate></item><item><title><![CDATA[Reply to dynamic_cast testen on Wed, 05 Jun 2013 18:39:39 GMT]]></title><description><![CDATA[<p>Ich übersehe wohl was. Wozu braucht man Upcasts und Downcasts?<br />
Die korrekte Lösung für das hier:</p>
<p>auchabgeleitet schrieb:</p>
<blockquote>
<pre><code>Basis *b=ListeVonPolymorphenObjekten[x];
if(b-&gt;GetTyp()==eTypA)
{
 Abgeleitet *a=basis_cast&lt;Abgeleitet*&gt;(b); // bummm schon hier!
 a-&gt;EineFunktionVonAbgeleitet();
}
</code></pre>
</blockquote>
<p>ist doch wohl sowas in der Art:</p>
<pre><code>struct Basis{
 virtual void rufDieRichtigeFunktionAuf(){
 }
};
struct Abgeleitet{
 void EineFunktionVonAbgeleitet();
 void rufDieRichtigeFunktionAuf(){
  EineFunktionVonAbgeleitet();
 }
};

...

Basis *b=ListeVonPolymorphenObjekten[x];
b-&gt;rufDieRichtigeFunktionAuf();
</code></pre>
<p>Jetzt, da RTTI angeschaltet ist sollte das doch funktionieren und der Compiler wird sich schon was Schlaues und Optimiertes für die Implementierung überlegen.</p>
<p>Wenn man das nicht will, weil die abgeleiteten Klassen zu verschieden sind, als dass man für alles eine virtuelle Funktion anlegen will, dann sollte man vielleicht nicht alles von der Basis ableiten und in einen Container stopfen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2328865</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2328865</guid><dc:creator><![CDATA[nwp3]]></dc:creator><pubDate>Wed, 05 Jun 2013 18:39:39 GMT</pubDate></item><item><title><![CDATA[Reply to dynamic_cast testen on Wed, 05 Jun 2013 20:01:43 GMT]]></title><description><![CDATA[<p>auchabgeleitet schrieb:</p>
<blockquote>
<pre><code class="language-cpp">for (auto a_type = typeid(A); a_type.name() != typeid(B).name();) {
//                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-- das ist richtig lahm
</code></pre>
</blockquote>
<p>Macht man ja auch nicht. <code>std::type_info</code> (und <code>std::type_index</code> ) ist direkt vergleichbar. Der Vergleich kann z.B. auch mit Integern implementiert werden.</p>
<p>Ich würde hier nicht zu viel spekulieren, die Performance von RTTI hängt massgeblich von der Compiler-Implementierung ab. Ausserdem hat man meist andere Probleme, wenn man RTTI benötigt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2328878</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2328878</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Wed, 05 Jun 2013 20:01:43 GMT</pubDate></item><item><title><![CDATA[Reply to dynamic_cast testen on Wed, 05 Jun 2013 20:28:42 GMT]]></title><description><![CDATA[<p>nwp3 schrieb:</p>
<blockquote>
<p>Ich übersehe wohl was. Wozu braucht man Upcasts und Downcasts?<br />
Die korrekte Lösung für das hier:</p>
<p>auchabgeleitet schrieb:</p>
<blockquote>
<pre><code>Basis *b=ListeVonPolymorphenObjekten[x];
if(b-&gt;GetTyp()==eTypA)
{
 Abgeleitet *a=basis_cast&lt;Abgeleitet*&gt;(b); // bummm schon hier!
 a-&gt;EineFunktionVonAbgeleitet();
}
</code></pre>
</blockquote>
<p>ist doch wohl sowas in der Art:</p>
<pre><code>struct Basis{
 virtual void rufDieRichtigeFunktionAuf(){
 }
};
struct Abgeleitet{
 void EineFunktionVonAbgeleitet();
 void rufDieRichtigeFunktionAuf(){
  EineFunktionVonAbgeleitet();
 }
};

...

Basis *b=ListeVonPolymorphenObjekten[x];
b-&gt;rufDieRichtigeFunktionAuf();
</code></pre>
<p>Jetzt, da RTTI angeschaltet ist sollte das doch funktionieren und der Compiler wird sich schon was Schlaues und Optimiertes für die Implementierung überlegen.</p>
<p>Wenn man das nicht will, weil die abgeleiteten Klassen zu verschieden sind, als dass man für alles eine virtuelle Funktion anlegen will, dann sollte man vielleicht nicht alles von der Basis ableiten und in einen Container stopfen.</p>
</blockquote>
<p>Das geht sogar ohne RTTI, entspricht aber nicht dem gestellten Problem, als da wäre mit Äpfeln und Birnen umzugehen ohne über Obst zu sprechen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2328886</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2328886</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Wed, 05 Jun 2013 20:28:42 GMT</pubDate></item></channel></rss>