<?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[Interfaces]]></title><description><![CDATA[<p>Hab grad n kleines verständnisproblem</p>
<p>also nehmen wir mal an ich hab so ein standard ableitungskonstrukt</p>
<pre><code class="language-cpp">class Base{};
class Derived1 : public Base{};
class Derived2 : public Base{};
</code></pre>
<p>soweit so gut<br />
jetzt will ich ein abstraktes interface für die basis zur verfügung stelln<br />
also änder ich das ganze in</p>
<pre><code class="language-cpp">class IBase{};
class Base : public IBase{};
class Derived1 : public Base{};
class Derived2 : public Base{};
</code></pre>
<p>wenn ich jetzt auch noch interfaces zu den abgeleiteten klassen anbieten will<br />
hab ich ein problem.<br />
die einzige lösung die mir bis jetzt eingefallen ist:</p>
<pre><code class="language-cpp">class IBase{};
class IDerived1{};
class IDerived2{};
class Base :  public IBase{};
class Derived1 : public Base, public IDerived1{};
class Derived2 : public Base, public IDerived1{};
</code></pre>
<p>was mir daran nich gefällt is folgendes:<br />
wenn ich eine IDerived1 instanz habe und eine funktion in IBase aufrufen will<br />
muss ich diese funktion abstrakt in IDerived1 definieren und in Derived1<br />
implementieren indem ich einfach die funktion von IBase aufrufe.</p>
<p>quasi so:</p>
<pre><code class="language-cpp">class IBase{ virtual void func() = 0;};
class IDerived1{virtual void func_umleitung() = 0; };
class Base :  public IBase{virtual void func(){//do something}};
class Derived1 : public Base, public IDerived1{virtual void func_umleitung(){IBase::func()}};
</code></pre>
<p>gibts dafür ne bessere lösung?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/222193/interfaces</link><generator>RSS for Node</generator><lastBuildDate>Mon, 05 Oct 2026 04:09:43 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/222193.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 09 Sep 2008 07:48:05 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Interfaces on Tue, 09 Sep 2008 07:48:05 GMT]]></title><description><![CDATA[<p>Hab grad n kleines verständnisproblem</p>
<p>also nehmen wir mal an ich hab so ein standard ableitungskonstrukt</p>
<pre><code class="language-cpp">class Base{};
class Derived1 : public Base{};
class Derived2 : public Base{};
</code></pre>
<p>soweit so gut<br />
jetzt will ich ein abstraktes interface für die basis zur verfügung stelln<br />
also änder ich das ganze in</p>
<pre><code class="language-cpp">class IBase{};
class Base : public IBase{};
class Derived1 : public Base{};
class Derived2 : public Base{};
</code></pre>
<p>wenn ich jetzt auch noch interfaces zu den abgeleiteten klassen anbieten will<br />
hab ich ein problem.<br />
die einzige lösung die mir bis jetzt eingefallen ist:</p>
<pre><code class="language-cpp">class IBase{};
class IDerived1{};
class IDerived2{};
class Base :  public IBase{};
class Derived1 : public Base, public IDerived1{};
class Derived2 : public Base, public IDerived1{};
</code></pre>
<p>was mir daran nich gefällt is folgendes:<br />
wenn ich eine IDerived1 instanz habe und eine funktion in IBase aufrufen will<br />
muss ich diese funktion abstrakt in IDerived1 definieren und in Derived1<br />
implementieren indem ich einfach die funktion von IBase aufrufe.</p>
<p>quasi so:</p>
<pre><code class="language-cpp">class IBase{ virtual void func() = 0;};
class IDerived1{virtual void func_umleitung() = 0; };
class Base :  public IBase{virtual void func(){//do something}};
class Derived1 : public Base, public IDerived1{virtual void func_umleitung(){IBase::func()}};
</code></pre>
<p>gibts dafür ne bessere lösung?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1578976</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1578976</guid><dc:creator><![CDATA[Sovok]]></dc:creator><pubDate>Tue, 09 Sep 2008 07:48:05 GMT</pubDate></item><item><title><![CDATA[Reply to Interfaces on Tue, 09 Sep 2008 07:53:25 GMT]]></title><description><![CDATA[<p>IDerived erbt von IBase</p>
<p>Aber das ist Java was du da schreibst. Du hast mit Base bereits eine Interface Definition - nimm Base und verzichte auf IBase.</p>
<p>PS:<br />
irgendwas passt da nicht. Warum haben Interfaces plötzlich ne implementierung. Wozu genau hast du IBase und Base? Was ist der Unterschied?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1578978</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1578978</guid><dc:creator><![CDATA[Shade Of Mine]]></dc:creator><pubDate>Tue, 09 Sep 2008 07:53:25 GMT</pubDate></item><item><title><![CDATA[Reply to Interfaces on Tue, 09 Sep 2008 08:15:14 GMT]]></title><description><![CDATA[<p>wenn IDerived von IBase erbt hab ich doch den guten alten diamond of death bzw.<br />
wär auch inhaltlich nicht richtig beide klassen auf Base zurückzuführen</p>
<p>ja hab ich auch schon dran gedacht... hat irgendwas von dem implements kram in<br />
java</p>
<p>IBase, IDerived1 und IDerived2 sind abstrakt d.h. kein konstruktor, keine<br />
variablen und viel wichtiger keine abhängigkeiten zu irgendwelchen headern<br />
oder bibliotheken</p>
<p>erzeugt werden die interfaces durch eine factory innerhalb einer dynamischen<br />
bibliothek die zur laufzeit nachgeladen wird</p>
<p>base, derived1 und derived2 sind die konkreten implementierungen deren header<br />
ich nicht aus der bibliothek geben will um die benutzung der funktionalität<br />
nach außen hin einfach zu halten</p>
<p>vielleicht wärs besser wenn ich IBase einfach weglass und die<br />
funktionsdefinitionen bei beiden(IDerived1 und IDerived2) reinschreib</p>
<p>quasi so:</p>
<pre><code class="language-cpp">class IDerived1{};
class IDerived2{};
class Base{};
class Derived1 : public Base, public IDerived1{};
class Derived2 : public Base, public IDerived2{};
</code></pre>
<p>was meint der meister dazu? <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/1579003</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1579003</guid><dc:creator><![CDATA[Sovok]]></dc:creator><pubDate>Tue, 09 Sep 2008 08:15:14 GMT</pubDate></item><item><title><![CDATA[Reply to Interfaces on Tue, 09 Sep 2008 08:41:25 GMT]]></title><description><![CDATA[<p>[quote=&quot;Sovok&quot;]</p>
<blockquote>
<pre><code class="language-cpp">class IDerived1{};
class IDerived2{};
class Base{};
class Derived1 : public Base, public IDerived1{};
class Derived2 : public Base, public IDerived2{};
</code></pre>
<p>was meint der meister dazu? <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>
</blockquote>
<p>Sobald du von Derived erbst, hast du wieder das selbe Problem. Ich würde deshalb folgendes vorschlagen:</p>
<pre><code class="language-cpp">class IBase {};
class Base : public IBase {};
class IDerived : public IBase {}
class Derived : public IDerived {}
</code></pre>
<p>Das Problem dabei ist, du kannst in Derived nicht von Base erben. Es sei denn wir tricksen mit dem pimpl Idiom rum.</p>
<pre><code class="language-cpp">class IBase { virtual void foo()=0; };
class Base : public IBase { void foo(){} };
class IDerived : public IBase { virtual void bar()=0; }
class Derived : public IDerived {
ConcreteDerived* impl;
void foo() { impl-&gt;foo(); }
void bar() { impl-&gt;bar(); }
};
class ConcreteDerived : public Base {
void foo() { }
void bar() { }
};
</code></pre>
<p>Wobei ConcreteDerived eben &quot;package private&quot; ist und du es nie nach aussen gibst. Derived ist quasi die fassade um die laufzeit polymorphie zu ermöglichen.</p>
<p>ConcreteDerived muss nur per forward declaration bekannt gemacht werden - du hast also nicht mehr abhängigkeiten in den public headern.</p>
<p>Wenn du dann auch ein Derived2 hättest das von Derived erben sollte, würde es dann so aussehen:</p>
<pre><code class="language-cpp">class IDerived2 : public IDerived { virtual void baz()=0; }
class Derived2 : public IDerived2 {
ConcreteDerived2* impl;
void foo() { impl-&gt;foo(); }
void bar() { impl-&gt;bar(); }
void baz() { impl-&gt;baz(); }
};
class ConcreteDerived2 : public ConcreteDerived {
void baz() { }
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1579019</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1579019</guid><dc:creator><![CDATA[Shade Of Mine]]></dc:creator><pubDate>Tue, 09 Sep 2008 08:41:25 GMT</pubDate></item><item><title><![CDATA[Reply to Interfaces on Tue, 09 Sep 2008 09:03:17 GMT]]></title><description><![CDATA[<p>Shade Of Mine schrieb:</p>
<blockquote>
<pre><code class="language-cpp">class IBase { virtual void foo()=0; };
class Base : public IBase { void foo(){} };
class IDerived : public IBase { virtual void bar()=0; }
class Derived : public IDerived {
ConcreteDerived* impl;
void foo() { impl-&gt;foo(); }
void bar() { impl-&gt;bar(); }
};
class ConcreteDerived : public Base {
void foo() { }
void bar() { }
};
</code></pre>
</blockquote>
<p>interessante idee <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f44d.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--thumbs_up"
      title=":+1:"
      alt="👍"
    /><br />
wenn dann also noch Derived ein friend von ConcreteDerived ist könnte ich<br />
innerhalb von Derived so tun als wäre Base eine Basisklasse von Derived</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1579040</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1579040</guid><dc:creator><![CDATA[Sovok]]></dc:creator><pubDate>Tue, 09 Sep 2008 09:03:17 GMT</pubDate></item><item><title><![CDATA[Reply to Interfaces on Tue, 09 Sep 2008 09:12:12 GMT]]></title><description><![CDATA[<p>Sovok schrieb:</p>
<blockquote>
<p>wenn dann also noch Derived ein friend von ConcreteDerived ist könnte ich<br />
innerhalb von Derived so tun als wäre Base eine Basisklasse von Derived</p>
</blockquote>
<p>Ich würde alle methoden an ConcreteDerived forwarden. Das mit dem friend habe ich jetzt nicht verstanden. Aber ja, im eigentlich muss Derived ein friend von ConcreteDerived sein.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1579050</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1579050</guid><dc:creator><![CDATA[Shade Of Mine]]></dc:creator><pubDate>Tue, 09 Sep 2008 09:12:12 GMT</pubDate></item><item><title><![CDATA[Reply to Interfaces on Tue, 09 Sep 2008 12:27:01 GMT]]></title><description><![CDATA[<p>Mal ganz doof gefragt: lässt sich sovas nicht mit virtual inheritance lösen?</p>
<pre><code class="language-cpp">struct IBase
{
    virtual void Foo() = 0;
};

struct IDerived : virtual IBase
{
    virtual void Bar() = 0;
};

struct Base : virtual IBase
{
    virtual void Foo() {}
};

struct Derived : virtual IDerived, virtual Base
{
    virtual void Bar() {}
};
</code></pre>
<p>Normalerweise ist virtual inheritance auch das was man will. Dass so wenig virtual inheritance verwendet wird liegt IMO eher daran dass es in den meisten Fällen keinen Unterschied macht - dort wo es einen Unterschied macht ist aber eher virtual inheritance das was man will, und nicht die &quot;normale&quot; Variante.<br />
Einziger Vorteil von &quot;normal&quot; (mal davon abgesehen dass man ein Keyword weniger tippen muss): man braucht weniger oft einen (vergleichsweise langsamen) dynamic_cast.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1579172</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1579172</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 09 Sep 2008 12:27:01 GMT</pubDate></item><item><title><![CDATA[Reply to Interfaces on Tue, 09 Sep 2008 12:34:26 GMT]]></title><description><![CDATA[<p>virtuelle vererbung ist die holzhammer methode für designprobleme.<br />
idR sollte man sie vermeiden und ich hatte noch nie eine situation wo sie nötig war.</p>
<p>hier ist virtuelle vererbung tragbar, aber imho ist mein design deutlich besser.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1579182</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1579182</guid><dc:creator><![CDATA[Shade Of Mine]]></dc:creator><pubDate>Tue, 09 Sep 2008 12:34:26 GMT</pubDate></item><item><title><![CDATA[Reply to Interfaces on Tue, 09 Sep 2008 12:38:10 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>Dass so wenig virtual inheritance verwendet wird liegt IMO eher daran dass es in den meisten Fällen keinen Unterschied macht...</p>
</blockquote>
<p>...und daran das es in vielen Büchern teilweise nicht, oder nur am Rande erwähnt wird.</p>
<p>cu André</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1579186</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1579186</guid><dc:creator><![CDATA[asc]]></dc:creator><pubDate>Tue, 09 Sep 2008 12:38:10 GMT</pubDate></item><item><title><![CDATA[Reply to Interfaces on Tue, 09 Sep 2008 14:12:30 GMT]]></title><description><![CDATA[<p>asc schrieb:</p>
<blockquote>
<p>...und daran das es in vielen Büchern teilweise nicht, oder nur am Rande erwähnt wird.</p>
</blockquote>
<p>ihr kennt die fallstricke von virtueller vererbung aber schon, oder?</p>
<p>virtuelle vererbung ist die logische antwort auf die symptome eines deadly diamond. aber symptome zu bekämpfen ist doof...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1579264</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1579264</guid><dc:creator><![CDATA[Shade Of Mine]]></dc:creator><pubDate>Tue, 09 Sep 2008 14:12:30 GMT</pubDate></item><item><title><![CDATA[Reply to Interfaces on Wed, 10 Sep 2008 16:20:55 GMT]]></title><description><![CDATA[<p>Shade Of Mine schrieb:</p>
<blockquote>
<p>asc schrieb:</p>
<blockquote>
<p>...und daran das es in vielen Büchern teilweise nicht, oder nur am Rande erwähnt wird.</p>
</blockquote>
<p>ihr kennt die fallstricke von virtueller vererbung aber schon, oder?</p>
</blockquote>
<p>Wenn du schon so fragst... vermutlich nicht? Magst du mich aufklären?</p>
<blockquote>
<p>virtuelle vererbung ist die logische antwort auf die symptome eines deadly diamond. aber symptome zu bekämpfen ist doof...</p>
</blockquote>
<p>Der &quot;dreaded diamond&quot; ist IMO nur dann schlimm und zu fürchten wenn die Klasse &quot;oben&quot; Daten enthält. Wenn diese klasse ein reines Interface ist sehe ich echt kein Problem, und verstehe auch nicht was man da gegen virtuelle Vererbung haben sollte/könnte/müsste.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1579864</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1579864</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Wed, 10 Sep 2008 16:20:55 GMT</pubDate></item><item><title><![CDATA[Reply to Interfaces on Thu, 11 Sep 2008 20:37:33 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>Shade Of Mine schrieb:</p>
<blockquote>
<p>asc schrieb:</p>
<blockquote>
<p>...und daran das es in vielen Büchern teilweise nicht, oder nur am Rande erwähnt wird.</p>
</blockquote>
<p>ihr kennt die fallstricke von virtueller vererbung aber schon, oder?</p>
</blockquote>
<p>Wenn du schon so fragst... vermutlich nicht? <strong>Magst du mich aufklären?</strong></p>
</blockquote>
]]></description><link>https://www.c-plusplus.net/forum/post/1580498</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1580498</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Thu, 11 Sep 2008 20:37:33 GMT</pubDate></item></channel></rss>