<?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[Ist hier dynamic_cast ok?]]></title><description><![CDATA[<p>Hallo,</p>
<p>Ich habe folgendes Design: Eine Basisklasse Foo und eine davon abgeleitete Klasse FooDerived.<br />
Dann eine Klasse Bar und eine abgeleitete Klasse BarDerived. Foo hat einen Zeiger auf Bar:</p>
<pre><code class="language-cpp">class Foo {
    Bar* b:
public:
    Foo(Bar* _b) : b(_b) { }

}

public FooDerived : public Foo {
public:
    void fooDerivedMethod() { }
}

class Bar {
public:
   virtual void method(Foo* f) = 0;
}

class BarDerived : public Bar {
public:
    virtual void method(Foo* f) {
        // An dieser Stelle weiss ich, dass f IMMER vom Typ FooDerived ist. (BarDerived::method() kriegt IMMER nur FooDerived's)
        // An dieser Stelle brauche ich Zugriff auf die methode fooDerivedMethod(), die es nur in FooDerived gibt. Ist hier ein Downcast mit dynamic_cast ok?
        FooDerived* fd = dynamic_cast&lt;FooDerived*&gt;(f);
        fd-&gt;fooDerivedMethod(); // ist das ok?
    }
}
</code></pre>
<p>Die Frage ist im Kommentar. Danke!</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/287913/ist-hier-dynamic_cast-ok</link><generator>RSS for Node</generator><lastBuildDate>Sun, 16 Aug 2026 11:35:28 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/287913.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 07 Jun 2011 07:14:08 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Ist hier dynamic_cast ok? on Tue, 07 Jun 2011 07:14:08 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>Ich habe folgendes Design: Eine Basisklasse Foo und eine davon abgeleitete Klasse FooDerived.<br />
Dann eine Klasse Bar und eine abgeleitete Klasse BarDerived. Foo hat einen Zeiger auf Bar:</p>
<pre><code class="language-cpp">class Foo {
    Bar* b:
public:
    Foo(Bar* _b) : b(_b) { }

}

public FooDerived : public Foo {
public:
    void fooDerivedMethod() { }
}

class Bar {
public:
   virtual void method(Foo* f) = 0;
}

class BarDerived : public Bar {
public:
    virtual void method(Foo* f) {
        // An dieser Stelle weiss ich, dass f IMMER vom Typ FooDerived ist. (BarDerived::method() kriegt IMMER nur FooDerived's)
        // An dieser Stelle brauche ich Zugriff auf die methode fooDerivedMethod(), die es nur in FooDerived gibt. Ist hier ein Downcast mit dynamic_cast ok?
        FooDerived* fd = dynamic_cast&lt;FooDerived*&gt;(f);
        fd-&gt;fooDerivedMethod(); // ist das ok?
    }
}
</code></pre>
<p>Die Frage ist im Kommentar. Danke!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074391</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074391</guid><dc:creator><![CDATA[caster2]]></dc:creator><pubDate>Tue, 07 Jun 2011 07:14:08 GMT</pubDate></item><item><title><![CDATA[Reply to Ist hier dynamic_cast ok? on Tue, 07 Jun 2011 07:26:49 GMT]]></title><description><![CDATA[<p>Wenn Du weisst, dass immer ein <code>FooDerived</code> reingeht, wieso übergibst Du dann nicht gleich ein <code>FooDerived</code> ? Und nein, ein <code>dynamic_cast</code> ist hier aus meiner Sicht nicht sehr sinnvoll.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074396</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074396</guid><dc:creator><![CDATA[Tachyon]]></dc:creator><pubDate>Tue, 07 Jun 2011 07:26:49 GMT</pubDate></item><item><title><![CDATA[Reply to Ist hier dynamic_cast ok? on Tue, 07 Jun 2011 07:36:32 GMT]]></title><description><![CDATA[<p>Tachyon schrieb:</p>
<blockquote>
<p>Wenn Du weisst, dass immer ein <code>FooDerived</code> reingeht, wieso übergibst Du dann nicht gleich ein <code>FooDerived</code> ? Und nein, ein <code>dynamic_cast</code> ist hier aus meiner Sicht nicht sehr sinnvoll.</p>
</blockquote>
<p>Weil BarDerived ja nicht die einzige Klasse sein muss, die von Bar erbt. Es koennte z.b. Ein Bar2Derived : public Bar geben sowie ein Foo2Derived : Foo und dann bekommt Bar2Derived::method(Foo* f) ein Foo2Derived uebergeben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074401</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074401</guid><dc:creator><![CDATA[caster2]]></dc:creator><pubDate>Tue, 07 Jun 2011 07:36:32 GMT</pubDate></item><item><title><![CDATA[Reply to Ist hier dynamic_cast ok? on Tue, 07 Jun 2011 07:37:05 GMT]]></title><description><![CDATA[<p>Tachyon schrieb:</p>
<blockquote>
<p>Wenn Du weisst, dass immer ein <code>FooDerived</code> reingeht, wieso übergibst Du dann nicht gleich ein <code>FooDerived</code> ? Und nein, ein <code>dynamic_cast</code> ist hier aus meiner Sicht nicht sehr sinnvoll.</p>
</blockquote>
<pre><code class="language-cpp">FooDerived* fd = dynamic_cast&lt;FooDerived*&gt;(f);
if(!fd) wasTun()?
fd-&gt;fooDerivedMethod(); // ist das ok?
</code></pre>
<p>Die ganze Funktionalität des dynamic_cast brauchste hier nicht. static_cast reicht völlig. Weil Du sicher bist und das if oder gar das Gehangele am Baum nicht brauchst. Das würde ich hier auch nicht bezahlen wollen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074402</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074402</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Tue, 07 Jun 2011 07:37:05 GMT</pubDate></item><item><title><![CDATA[Reply to Ist hier dynamic_cast ok? on Tue, 07 Jun 2011 07:40:02 GMT]]></title><description><![CDATA[<p>caster2 schrieb:</p>
<blockquote>
<p>Tachyon schrieb:</p>
<blockquote>
<p>Wenn Du weisst, dass immer ein <code>FooDerived</code> reingeht, wieso übergibst Du dann nicht gleich ein <code>FooDerived</code> ? Und nein, ein <code>dynamic_cast</code> ist hier aus meiner Sicht nicht sehr sinnvoll.</p>
</blockquote>
<p>Weil BarDerived ja nicht die einzige Klasse sein muss, die von Bar erbt. Es koennte z.b. Ein Bar2Derived : public Bar geben sowie ein Foo2Derived : Foo und dann bekommt Bar2Derived::method(Foo* f) ein Foo2Derived uebergeben.</p>
</blockquote>
<p>Dann muss ich die Frage stellen, woher Du weißt, womit Du <code>Bar::method</code> aufrufen musst. Wie stellst Du sicher, dass immer die richtige Ableitung von <code>Foo</code> in <code>Bar::method</code> hineingeht?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074405</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074405</guid><dc:creator><![CDATA[Tachyon]]></dc:creator><pubDate>Tue, 07 Jun 2011 07:40:02 GMT</pubDate></item><item><title><![CDATA[Reply to Ist hier dynamic_cast ok? on Tue, 07 Jun 2011 07:44:51 GMT]]></title><description><![CDATA[<p>Das Design ist fehlerhaft. Du verletzt das <a href="http://en.wikipedia.org/wiki/Liskov_substitution_principle" rel="nofollow">Liskovsche Substitutionsprinzip</a>. Du engst die Bedingungen der Methode <code>void method(Foo* f);</code> in einer Unterklasse (BarDerived) ein, nämlich dass f ein FooDerived sein muss. Damit kannst du Bar Objekte nicht beliebig austauschen ohne ein fehlerhaftes Programm zu erhalten.<br />
Wenn Du mal dein tatsächliches Problem erklärst kann man dir vielleicht eine Alternative vorshclagen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074410</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074410</guid><dc:creator><![CDATA[brotbernd]]></dc:creator><pubDate>Tue, 07 Jun 2011 07:44:51 GMT</pubDate></item><item><title><![CDATA[Reply to Ist hier dynamic_cast ok? on Tue, 07 Jun 2011 08:02:44 GMT]]></title><description><![CDATA[<p>Naja, ich weiss eben in Unterklassen von Bar, was fuer Unterklassen in method() reinkommen.<br />
Mein konkreter Fall: Bar ist ein RenderSystem und Unterklassen sind zB D3D9RenderSystem oder OGLRenderSystem. Foo ist ein RenderTarget. RenderWindow erbt von RenderTarget und D3D9RenderWindow sowie OGLRenderWindow erbt von RenderWindow.</p>
<p>Nun habe ich eben folgende Methode:<br />
virtual void RenderSystem::swapBuffers(RenderWindow* win) = 0;<br />
Alle RenderSystems koennen den BackBuffer swappen, aber WIE das geht, ist abhaengig von der Render API. Und ein D3D9RenderSystem kriegt eben IMMER ein D3D9RenderWindow uebergeben und ein OGLRenderSystem IMMER ein OGLRenderWindow. Das D3D9RenderSystem muss auf eine Methode von D3D9RenderWindow zugreifen, die eben Direct3D9 spezifisch ist und die ein OGLRenderWindow nicht hat.</p>
<p>Drum mache ich das momentan so und es funktioniert ja auch wunderbar:</p>
<pre><code class="language-cpp">D3D9RenderSystem::swapBuffers(RenderWindow* win) {
   D3D9RenderWindow* wind3d = static_cast&lt;D3D9RenderWindow*&gt;(win);
   win3d-&gt;getSwapChain(); 
   // Ein D3D9RenderSystem kann eben nur ein D3D9RenderWindow bekommen
   ...
}
</code></pre>
<p>Ist das Design jetzt so verwerflich?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074426</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074426</guid><dc:creator><![CDATA[caster2]]></dc:creator><pubDate>Tue, 07 Jun 2011 08:02:44 GMT</pubDate></item><item><title><![CDATA[Reply to Ist hier dynamic_cast ok? on Tue, 07 Jun 2011 08:11:14 GMT]]></title><description><![CDATA[<p>caster2 schrieb:</p>
<blockquote>
<p>Ist das Design jetzt so verwerflich?</p>
</blockquote>
<p>Ja. Denn:</p>
<p>caster2 schrieb:</p>
<blockquote>
<p>D3D9RenderSystem kriegt eben IMMER ein D3D9RenderWindow</p>
</blockquote>
<p>Du hast also an der Stelle an der Du <code>swapBuffers</code> aufrufst ein <em>konkretes</em> RenderSystem und nicht die Basisklasse. <em>Du weiß also, was Du für einen RenderSystem-Typen hast</em>. Wenn Du das aber weisst, wo ist dann der Sinn darin, <code>swapBuffers</code> virtuell in der Basisklasse festulegen? Du kannst einfach eine <code>D3D9RenderSystem::swapBuffers</code> anbieten, das gleich den passenden Typen bekommt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074435</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074435</guid><dc:creator><![CDATA[Tachyon]]></dc:creator><pubDate>Tue, 07 Jun 2011 08:11:14 GMT</pubDate></item><item><title><![CDATA[Reply to Ist hier dynamic_cast ok? on Tue, 07 Jun 2011 08:28:50 GMT]]></title><description><![CDATA[<p>Tachyon schrieb:</p>
<blockquote>
<p>caster2 schrieb:</p>
<blockquote>
<p>Ist das Design jetzt so verwerflich?</p>
</blockquote>
<p>Ja. Denn:</p>
<p>caster2 schrieb:</p>
<blockquote>
<p>D3D9RenderSystem kriegt eben IMMER ein D3D9RenderWindow</p>
</blockquote>
<p>Du hast also an der Stelle an der Du <code>swapBuffers</code> aufrufst ein <em>konkretes</em> RenderSystem und nicht die Basisklasse. <em>Du weiß also, was Du für einen RenderSystem-Typen hast</em>. Wenn Du das aber weisst, wo ist dann der Sinn darin, <code>swapBuffers</code> virtuell in der Basisklasse festulegen? Du kannst einfach eine <code>D3D9RenderSystem::swapBuffers</code> anbieten, das gleich den passenden Typen bekommt.</p>
</blockquote>
<p>Dann verlager ich aber nur das Problem. Ein RenderTarget hat bei mir einen Zeiger auf ein RenderSystem (Jedes RenderTarget wird von einem RenderSystem erzeugt).<br />
Der Aufruf von swapBuffers() findet dann in der Basisklasse RenderTarget statt, z.B.:</p>
<pre><code class="language-cpp">RenderTarget::RenderTarget(RenderSystem* r) : mRenderSystem(r) { }

So wird ein D3D9RenderWindow erzeugt: new D3D9RenderWindow(d3d9RenderSystem);
Bei einem D3D9RenderWindow ist mRenderSystem also immer vom Typ D3D9RenderSystem.

D3D9RenderWindow::foo() {
   mRenderSystem-&gt;swapBuffers(this); // In einem D3D9RenderWindow ist mRenderSystem vom Typ D3D9RenderWindow.
}
</code></pre>
<p>Wenn ich jetzt swapBuffers aus RenderWindow entferne und in die Subklassen verschiebe (also D3D9RenderSystem::swapBuffers(D3D9RenderWindow*) statt RenderSystem::swapBuffers(RenderWindow*), dann muesste ich jetzt aber in D3D9RenderWindow::foo() casten, sprich:</p>
<pre><code class="language-cpp">D3D9RenderWindow::foo() {
   // geht nicht mehr:mRenderSystem-&gt;swapBuffers(this); 
   D3D9RenderSystem* d3d9rs = static_cast&lt;mRenderSystem&gt;();
   d3d9rs-&gt;swapBuffers(this);
}
</code></pre>
<p>Ich hatte den Downcast also nur verschoben;/</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074444</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074444</guid><dc:creator><![CDATA[camper2]]></dc:creator><pubDate>Tue, 07 Jun 2011 08:28:50 GMT</pubDate></item><item><title><![CDATA[Reply to Ist hier dynamic_cast ok? on Tue, 07 Jun 2011 08:37:30 GMT]]></title><description><![CDATA[<p>Dann nimm <code>mRenderSystem</code> aus <code>RenderTarget</code> raus und lass jedes RenderTarget selber seine RenderSystem Referenz halten:</p>
<pre><code class="language-cpp">class D3D9RenderWindow : public RenderTarget
{
public:
    D3D9RenderWindow(D3D9RenderSystem* r) :mRenderSystem(r){}
private:
    D3D9RenderSystem * mRenderSystem;
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2074451</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074451</guid><dc:creator><![CDATA[brotbernd]]></dc:creator><pubDate>Tue, 07 Jun 2011 08:37:30 GMT</pubDate></item><item><title><![CDATA[Reply to Ist hier dynamic_cast ok? on Tue, 07 Jun 2011 08:52:53 GMT]]></title><description><![CDATA[<p>brotbernd schrieb:</p>
<blockquote>
<p>Dann nimm <code>mRenderSystem</code> aus <code>RenderTarget</code> raus und lass jedes RenderTarget selber seine RenderSystem Referenz halten:</p>
</blockquote>
<p>Das geht nicht, weil RenderTarget Methoden an vielen Stellen mRenderSystem benutzt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074464</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074464</guid><dc:creator><![CDATA[caster2]]></dc:creator><pubDate>Tue, 07 Jun 2011 08:52:53 GMT</pubDate></item><item><title><![CDATA[Reply to Ist hier dynamic_cast ok? on Tue, 07 Jun 2011 09:00:34 GMT]]></title><description><![CDATA[<p>caster2 schrieb:</p>
<blockquote>
<p>brotbernd schrieb:</p>
<blockquote>
<p>Dann nimm <code>mRenderSystem</code> aus <code>RenderTarget</code> raus und lass jedes RenderTarget selber seine RenderSystem Referenz halten:</p>
</blockquote>
<p>Das geht nicht, weil RenderTarget Methoden an vielen Stellen mRenderSystem benutzt.</p>
</blockquote>
<p>Jetzt ist bei mir auch die Warnlampe angegangen.<br />
Ich fürchte, da stimmt was nicht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074473</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074473</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Tue, 07 Jun 2011 09:00:34 GMT</pubDate></item><item><title><![CDATA[Reply to Ist hier dynamic_cast ok? on Tue, 07 Jun 2011 09:06:00 GMT]]></title><description><![CDATA[<p>volkard schrieb:</p>
<blockquote>
<p>caster2 schrieb:</p>
<blockquote>
<p>brotbernd schrieb:</p>
<blockquote>
<p>Dann nimm <code>mRenderSystem</code> aus <code>RenderTarget</code> raus und lass jedes RenderTarget selber seine RenderSystem Referenz halten:</p>
</blockquote>
<p>Das geht nicht, weil RenderTarget Methoden an vielen Stellen mRenderSystem benutzt.</p>
</blockquote>
<p>Jetzt ist bei mir auch die Warnlampe angegangen.<br />
Ich fürchte, da stimmt was nicht.</p>
</blockquote>
<p>Ich bin offen fuer Verbesserungsvorschlaege;)</p>
<p>Allerdings sehe ich nicht so recht das Problem. Ein RenderTarget benutzt eben die Methoden von RenderSystem, da prinzipiell alle RenderSystems gleich arbeiten. Nur in einem einzigen Fall: In RenderSystem::swapBuffers(RenderWindow*) braucht das D3DRenderSystem Zugriff auf D3DRenderWindow::SwapChain. Ein OGLRenderSystem braucht diesen Zugriff nicht, denn da gibt es nicht mal SwapChains. Keine Ahnung, wie ich das anders machen sollte als mit dem EINEN cast.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074480</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074480</guid><dc:creator><![CDATA[caster2]]></dc:creator><pubDate>Tue, 07 Jun 2011 09:06:00 GMT</pubDate></item><item><title><![CDATA[Reply to Ist hier dynamic_cast ok? on Tue, 07 Jun 2011 09:14:39 GMT]]></title><description><![CDATA[<p>Warum hält das RenderTarget einen Zeiger auf das RenderSystem?</p>
<p>Ich habe leider keine Ahnung von OpenGL oder DirectX, aber für mich hört es sich sinnvoller an, die RenderTargets an das entsprechende RenderSystem zu übergeben und nicht umgekehrt...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074488</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074488</guid><dc:creator><![CDATA[bmario]]></dc:creator><pubDate>Tue, 07 Jun 2011 09:14:39 GMT</pubDate></item><item><title><![CDATA[Reply to Ist hier dynamic_cast ok? on Tue, 07 Jun 2011 09:22:16 GMT]]></title><description><![CDATA[<p>caster2 schrieb:</p>
<blockquote>
<p>brotbernd schrieb:</p>
<blockquote>
<p>Dann nimm <code>mRenderSystem</code> aus <code>RenderTarget</code> raus und lass jedes RenderTarget selber seine RenderSystem Referenz halten:</p>
</blockquote>
<p>Das geht nicht, weil RenderTarget Methoden an vielen Stellen mRenderSystem benutzt.</p>
</blockquote>
<pre><code class="language-cpp">class RenderTarget
{
private:
    virtual const RenderSystem* GetRenderSystem() const = 0;
}
class D3D9Renderwindow : public RenderTarget
{
private:
    D3D9RenderSystem mRenderSystem;
    const RenderSystem&amp; GetRenderSystem() const { return mRenderSystem; }
}
</code></pre>
<p>caster2 schrieb:</p>
<blockquote>
<p>Ein RenderTarget benutzt eben die Methoden von RenderSystem, da prinzipiell alle RenderSystems gleich arbeiten. Nur in einem einzigen Fall: In RenderSystem::swapBuffers(RenderWindow*) braucht das D3DRenderSystem Zugriff auf D3DRenderWindow::SwapChain.</p>
</blockquote>
<p>Prinzipiell gleich ist eben nicht gleich. Unterscheidet sich D3DRenderWindow in nur einem winzigen Punkt von anderen RenderWindows, dann ist D3DRenderWindow kein RenderWindow (siehe oben: Liskov...).</p>
<p>Für mich klingt das irgendwie alles nach einem unheimlich komplexen System, das überhaupt keine Komplexität benötigt. Sei sparsam mit Vererbungen! Es muss nicht irgendwie alles mit allem verwandt sein, nur weil man versucht OOP zu machen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074494</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074494</guid><dc:creator><![CDATA[brotbernd]]></dc:creator><pubDate>Tue, 07 Jun 2011 09:22:16 GMT</pubDate></item><item><title><![CDATA[Reply to Ist hier dynamic_cast ok? on Tue, 07 Jun 2011 09:24:11 GMT]]></title><description><![CDATA[<p>bmario schrieb:</p>
<blockquote>
<p>Warum hält das RenderTarget einen Zeiger auf das RenderSystem?.</p>
</blockquote>
<p>Weil jedes RenderTarget eben Funktionalitaet des RenderSystems braucht. Wenn ein RenderTarget geupdatet werden soll, muessen bestimmte Puffer geleert werden. Und das ist Aufgabe des RenderSystems.</p>
<p>bmario schrieb:</p>
<blockquote>
<p>Ich habe leider keine Ahnung von OpenGL oder DirectX, aber für mich hört es sich sinnvoller an, die RenderTargets an das entsprechende RenderSystem zu übergeben und nicht umgekehrt...</p>
</blockquote>
<p>So ist es auch bereits. Die RenderTargets werden vom RenderSystem erzeugt und kriegen einen Zeiger aufs RenderSystem (this) mit. Quasi einen Zeiger auf ihren Erzeuger.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074495</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074495</guid><dc:creator><![CDATA[caster2]]></dc:creator><pubDate>Tue, 07 Jun 2011 09:24:11 GMT</pubDate></item><item><title><![CDATA[Reply to Ist hier dynamic_cast ok? on Tue, 07 Jun 2011 09:27:04 GMT]]></title><description><![CDATA[<p>brotbernd schrieb:</p>
<blockquote>
<p>Prinzipiell gleich ist eben nicht gleich. Unterscheidet sich D3DRenderWindow in nur einem winzigen Punkt von anderen RenderWindows, dann ist D3DRenderWindow kein RenderWindow (siehe oben: Liskov...).</p>
</blockquote>
<p>Ich verletze nirgends das LSP. Ein D3D9RenderWindow HAT alle Methoden eines RenderWindow und fuellt diese auch sinnvoll aus!</p>
<p>brotbernd schrieb:</p>
<blockquote>
<p>Für mich klingt das irgendwie alles nach einem unheimlich komplexen System, das überhaupt keine Komplexität benötigt. Sei sparsam mit Vererbungen! Es muss nicht irgendwie alles mit allem verwandt sein, nur weil man versucht OOP zu machen.</p>
</blockquote>
<p>Was ist denn an 2 Basisklassen bitte Komplex? Simpler als &quot;Ein D3D9RenderSystem IST ein RenderSystem&quot; und &quot;Ein D3D9RenderWindow IST ein RenderWindow IST ein RenderTarget&quot; gehts ja nicht mehr.<br />
Abgesehen davon ist das &quot;Wrappen&quot; von Render APIs einigermassen komplex. An manchen stellen unterscheiden sie sich eben doch deutlich.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074498</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074498</guid><dc:creator><![CDATA[caster2]]></dc:creator><pubDate>Tue, 07 Jun 2011 09:27:04 GMT</pubDate></item><item><title><![CDATA[Reply to Ist hier dynamic_cast ok? on Tue, 07 Jun 2011 09:29:54 GMT]]></title><description><![CDATA[<p>Die Erfahrung lehrt mich dass es nicht wirklich sinnvoll ist eine 3D API auf dieser Ebene zu kapseln auf der dus gerade versuchst. Bau lieber einen Renderer der ein Interface bietet für das was du eigentlich damit anstellen willst und implementier dann dieses Interface jeweils mit D3D bzw. OpenGL. Ein downcast ist ein Symptom für sehr kaputtes Design und selbst abgesehen davon willst du hier schon um der Performance willen keinen dynamic_cast. Einen OOP Wrapper für OpenGL schreiben willst du nicht, glaub mir. Mit dem komischen Objektmodell von OpenGL endet das nur in Trauer und Schmerz...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074499</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074499</guid><dc:creator><![CDATA[dot]]></dc:creator><pubDate>Tue, 07 Jun 2011 09:29:54 GMT</pubDate></item><item><title><![CDATA[Reply to Ist hier dynamic_cast ok? on Tue, 07 Jun 2011 09:28:58 GMT]]></title><description><![CDATA[<p>dot schrieb:</p>
<blockquote>
<p>Die Erfahrung lehrt mich dass es nicht wirklich sinnvoll ist eine 3D API auf dieser Ebene zu kapseln auf der dus gerade versuchst. Bau lieber einen Renderer der ein Interface bietet für das was du eigentlich damit anstellen willst und implementier dann dieses Interface jeweils mit D3D bzw. OpenGL. Einen OOP Wrapper für OpenGL schreiben willst du nicht, glaub mir. Mit dem komischen Objektmodell von OpenGL endet das nur in Trauer und Schmerz...</p>
</blockquote>
<p>RenderSystem IST mein Interface zu den Render APIs....</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074501</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074501</guid><dc:creator><![CDATA[caster2]]></dc:creator><pubDate>Tue, 07 Jun 2011 09:28:58 GMT</pubDate></item><item><title><![CDATA[Reply to Ist hier dynamic_cast ok? on Tue, 07 Jun 2011 09:34:45 GMT]]></title><description><![CDATA[<p>caster2 schrieb:</p>
<blockquote>
<p>RenderSystem IST mein Interface zu den Render APIs....</p>
</blockquote>
<p>Ist mir klar. Was ich damit sagen wollte ist: Dein Interface ist imo zu low-level. Du versuchst einfach nur D3D bzw. OpenGL hinter einen Layer zu stellen der exakt den gleichen Abstraktionsgrad hat wie die APIs selbst. Und genau das ist meiner Erfahrung nach absolut nicht sinnvoll. Glaub mir, ich hab schon oft genug solche Wrapper geschrieben. Vor allem OpenGL in C++ zu wrappen ist einfach nur pita <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/2074503</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074503</guid><dc:creator><![CDATA[dot]]></dc:creator><pubDate>Tue, 07 Jun 2011 09:34:45 GMT</pubDate></item><item><title><![CDATA[Reply to Ist hier dynamic_cast ok? on Tue, 07 Jun 2011 09:38:08 GMT]]></title><description><![CDATA[<p>caster2 schrieb:</p>
<blockquote>
<p>Ich verletze nirgends das LSP. Ein D3D9RenderWindow HAT alle Methoden eines RenderWindow und fuellt diese auch sinnvoll aus!</p>
</blockquote>
<p>Du verletzt das LSP z.B. an dieser Stelle:</p>
<pre><code class="language-cpp">D3D9RenderSystem::swapBuffers(RenderWindow* win)
</code></pre>
<p>LSP schrieb:</p>
<blockquote>
<p>Preconditions cannot be strengthened in a subtype</p>
</blockquote>
<p><code>RenderSystem::swapBuffers</code> hat zur Bedingung, dass <code>*win</code> ein gültiger Zeiger auf irgendeine <code>RenderWindow</code> Instanz ist.<br />
<code>D3D9RenderSystem::swapBuffers</code> hat die Bedingung dass <code>*win</code> ein Zeiger auf ein D3D9RenderWindow ist. Du kannst also D3D9RenderSystem nicht durch ein andereres substituieren. Das ist nun wirklich eine eindeutige Verletzung.</p>
<p>D3D9RenderSystem kann nicht jedes RenderWindow behandeln, daher ist diese Abstraktion an dieser Stelle einfach sinnlos.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074505</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074505</guid><dc:creator><![CDATA[brotbernd]]></dc:creator><pubDate>Tue, 07 Jun 2011 09:38:08 GMT</pubDate></item><item><title><![CDATA[Reply to Ist hier dynamic_cast ok? on Tue, 07 Jun 2011 09:41:09 GMT]]></title><description><![CDATA[<p>brotbernd schrieb:</p>
<blockquote>
<p>D3D9RenderSystem kann nicht jedes RenderWindow behandeln, daher ist diese Abstraktion an dieser Stelle einfach sinnlos.</p>
</blockquote>
<p>Stimmt, aber da es nur D3D9RenderWindows kriegen kann, sehe ich damit kein Problem. Vor allem faellt mir nichts eleganteres ein.</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/6496">@Dot</a>: Ich weiss. Das abstrahieren von Render APIs ist immer ein Schmerz im Hintern und OpenGL ganz besonders. Ich wage zu behaupten, dass ein 100% elegantes Wrappen beider APIs ohne kleinere Hacks unmoeglich ist. Dazu sind sie teilweise einfach zu unterschiedlich. Ich sag nur Contexts vs Swap Chains, Lost Devices etc.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074507</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074507</guid><dc:creator><![CDATA[caster2]]></dc:creator><pubDate>Tue, 07 Jun 2011 09:41:09 GMT</pubDate></item><item><title><![CDATA[Reply to Ist hier dynamic_cast ok? on Tue, 07 Jun 2011 09:54:36 GMT]]></title><description><![CDATA[<p>caster2 schrieb:</p>
<blockquote>
<p>Stimmt, aber da es nur D3D9RenderWindows kriegen kann, sehe ich damit kein Problem. Vor allem faellt mir nichts eleganteres ein.</p>
</blockquote>
<p>Und was war mit diesem Vorschlag</p>
<pre><code class="language-cpp">class RenderSystem
{
public:
    virtual void MachWas() const = 0;
};

class RenderTarget
{
public:
    void TuWas()
    {
        GetRenderSystem()-&gt;MachWas();
        Schwipp();
    }
private:
    virtual void Schwipp() = 0;
    virtual const RenderSystem* GetRenderSystem() const = 0;
};

class D3RenderWindow;
class D3RenderSystem : public RenderSystem
{
public:
    void MachWas() const { std::cout &lt;&lt; &quot;D3RenderSystem macht was\n&quot;; }
    void Schwapp(D3RenderWindow&amp; window){}

};

class D3RenderWindow : public RenderTarget
{
public:
    D3RenderSystem mRenderSystem;
    void Schwipp()
    {
        mRenderSystem.Schwapp(*this);
    }
    const RenderSystem* GetRenderSystem() const
    {
        return &amp;mRenderSystem;
    }
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2074513</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074513</guid><dc:creator><![CDATA[brotbernd]]></dc:creator><pubDate>Tue, 07 Jun 2011 09:54:36 GMT</pubDate></item><item><title><![CDATA[Reply to Ist hier dynamic_cast ok? on Tue, 07 Jun 2011 10:00:47 GMT]]></title><description><![CDATA[<p>caster2 schrieb:</p>
<blockquote>
<p>Ich wage zu behaupten, dass ein 100% elegantes Wrappen beider APIs ohne kleinere Hacks unmoeglich ist.</p>
</blockquote>
<p>Ja definitiv.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074514</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074514</guid><dc:creator><![CDATA[dot]]></dc:creator><pubDate>Tue, 07 Jun 2011 10:00:47 GMT</pubDate></item><item><title><![CDATA[Reply to Ist hier dynamic_cast ok? on Tue, 07 Jun 2011 10:05:02 GMT]]></title><description><![CDATA[<p>dot schrieb:</p>
<blockquote>
<p>caster2 schrieb:</p>
<blockquote>
<p>Ich wage zu behaupten, dass ein 100% elegantes Wrappen beider APIs ohne kleinere Hacks unmoeglich ist.</p>
</blockquote>
<p>Ja definitiv.</p>
</blockquote>
<p>Im Grunde gehts mir nur darum die Anzahl Hacks zu minimieren. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /> Ganz vermeiden ist unmoeglich.</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/9203">@brotbernd</a>: Danke! Hab leider im Moment keinen Zugriff auf meinen echten Code und kann deshalb gerade nicht sagen, ob das an irgend einer Stelle Probleme geben koennte. Aber sieht sehr interessant aus! <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2074516</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074516</guid><dc:creator><![CDATA[caster2]]></dc:creator><pubDate>Tue, 07 Jun 2011 10:05:02 GMT</pubDate></item><item><title><![CDATA[Reply to Ist hier dynamic_cast ok? on Tue, 07 Jun 2011 10:13:43 GMT]]></title><description><![CDATA[<p>caster2 schrieb:</p>
<blockquote>
<p>Ganz vermeiden ist unmoeglich.</p>
</blockquote>
<p>Man könnte es vermeiden sinnlose Wrapper zu schreiben, dann braucht man auch keine Hacks und spart unnötigen Overhead <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/2074522</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2074522</guid><dc:creator><![CDATA[dot]]></dc:creator><pubDate>Tue, 07 Jun 2011 10:13:43 GMT</pubDate></item></channel></rss>