<?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[wieder spaß mit vererbung :-)]]></title><description><![CDATA[<p>hallo,<br />
also ich hab mal wieder ein problem mit der vererbung und virtuellen funktionen.<br />
folgender abstrahierter code:</p>
<pre><code class="language-cpp">class A
{
	public:
		virtual A &amp;foo() = 0;
};

class B: virtual public A
{
	public:
//		B &amp;foo(){A::foo();/*....*/};
		B &amp;foo(int para){A::foo();/*....*/ return *this;};
};

class D: virtual public A
{
	public:
		D &amp;foo(){/*....*/return *this;};
};

class C: virtual public B, virtual private D
{
	public:
		C &amp;foo(){/*....*/return *this;};
};

void foo2(B &amp;b)
{
	b.foo();// Fehler
};

int main()
{
	C c;
	c.foo();
	foo2(c);
	return 0;
};
</code></pre>
<p>folgende fehlermeldung</p>
<pre><code>error C2660: 'B::foo': Funktion akzeptiert keine 0 Argumente
</code></pre>
<p>folgendes wenn ich das auskommentiert wieder einkommentiere</p>
<pre><code>error C2250: &quot;C&quot;: Mehrdeutige Vererbung von &quot;B &amp;A::foo(void)&quot;
</code></pre>
<p>letzters denke ich ist mir klar, liegt daran dass ich in C von B und D erbe. die andere fehlermeldung ist mir nicht so ganz klar, da die methode foo() ja eigentlich in C definiert wird und ich bei der Funktion foo2() ja auch eine Referenz übergebe, er also schon weiß das ein C Objekt dahintersteckt.<br />
ich könnte mir vorstellen, dass es daran liegt das A und B abstrakt sind, allerdings kann ja bei foo2() nur ein Objekt übergeben werden, das die funktion foo() auch definiert hat, womit es dann eigentlich wiederum kein problem wäre.<br />
ich bräuchte also mal wieder rat.<br />
danke schonmal im voraus.</p>
<p>PS: wen der hintergrund der vererbungsstruktur interessiert:<br />
A = container (abstrakt)<br />
B = priority-queue (abstrakt)<br />
D = array<br />
C = d-är heap (d=2 binär, d=3 tertiär, ...)<br />
eigentlich sind das alles noch templates, aber das hab ich jetzt mal weggelassen, da es nichts wesentliches beiträgt, denke ich zumindest.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/240357/wieder-spaß-mit-vererbung</link><generator>RSS for Node</generator><lastBuildDate>Mon, 21 Sep 2026 22:27:57 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/240357.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 05 May 2009 18:50:53 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to wieder spaß mit vererbung :-) on Tue, 05 May 2009 18:50:53 GMT]]></title><description><![CDATA[<p>hallo,<br />
also ich hab mal wieder ein problem mit der vererbung und virtuellen funktionen.<br />
folgender abstrahierter code:</p>
<pre><code class="language-cpp">class A
{
	public:
		virtual A &amp;foo() = 0;
};

class B: virtual public A
{
	public:
//		B &amp;foo(){A::foo();/*....*/};
		B &amp;foo(int para){A::foo();/*....*/ return *this;};
};

class D: virtual public A
{
	public:
		D &amp;foo(){/*....*/return *this;};
};

class C: virtual public B, virtual private D
{
	public:
		C &amp;foo(){/*....*/return *this;};
};

void foo2(B &amp;b)
{
	b.foo();// Fehler
};

int main()
{
	C c;
	c.foo();
	foo2(c);
	return 0;
};
</code></pre>
<p>folgende fehlermeldung</p>
<pre><code>error C2660: 'B::foo': Funktion akzeptiert keine 0 Argumente
</code></pre>
<p>folgendes wenn ich das auskommentiert wieder einkommentiere</p>
<pre><code>error C2250: &quot;C&quot;: Mehrdeutige Vererbung von &quot;B &amp;A::foo(void)&quot;
</code></pre>
<p>letzters denke ich ist mir klar, liegt daran dass ich in C von B und D erbe. die andere fehlermeldung ist mir nicht so ganz klar, da die methode foo() ja eigentlich in C definiert wird und ich bei der Funktion foo2() ja auch eine Referenz übergebe, er also schon weiß das ein C Objekt dahintersteckt.<br />
ich könnte mir vorstellen, dass es daran liegt das A und B abstrakt sind, allerdings kann ja bei foo2() nur ein Objekt übergeben werden, das die funktion foo() auch definiert hat, womit es dann eigentlich wiederum kein problem wäre.<br />
ich bräuchte also mal wieder rat.<br />
danke schonmal im voraus.</p>
<p>PS: wen der hintergrund der vererbungsstruktur interessiert:<br />
A = container (abstrakt)<br />
B = priority-queue (abstrakt)<br />
D = array<br />
C = d-är heap (d=2 binär, d=3 tertiär, ...)<br />
eigentlich sind das alles noch templates, aber das hab ich jetzt mal weggelassen, da es nichts wesentliches beiträgt, denke ich zumindest.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1706079</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1706079</guid><dc:creator><![CDATA[StarCraftFeuerteufel]]></dc:creator><pubDate>Tue, 05 May 2009 18:50:53 GMT</pubDate></item><item><title><![CDATA[Reply to wieder spaß mit vererbung :-) on Tue, 05 May 2009 21:21:09 GMT]]></title><description><![CDATA[<p>Du überschreibst in C ja keine Methode. Das B::foo nimmt ja einen Parameter und noch dazu hat es einen anderen Rückgabetyp.<br />
Ergo hast du eine neue Methode, die du mit einem B nicht aufrufen kannst. (Bin nur kurz drübergegangen, also keine Gewähr auf Richtigkeit).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1706141</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1706141</guid><dc:creator><![CDATA[Cox]]></dc:creator><pubDate>Tue, 05 May 2009 21:21:09 GMT</pubDate></item><item><title><![CDATA[Reply to wieder spaß mit vererbung :-) on Wed, 06 May 2009 00:05:33 GMT]]></title><description><![CDATA[<p>Hi,</p>
<p>im ersten Fall überdeckt der Name B::foo A::foo und somit gibts in diesen Scoop nur foo(int). Überladen funktioniert nicht über Klassen hinweg, nur im selben Scoop.</p>
<p>Im zweiten auskommentierten Fall sehe ich keinen Fehler, poste mal bitte genau den Code, der diesen Fehler verursacht.</p>
<p>Desweiteren kannst du dir die virtuals bei class C sparen <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/1706176</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1706176</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Wed, 06 May 2009 00:05:33 GMT</pubDate></item><item><title><![CDATA[Reply to wieder spaß mit vererbung :-) on Wed, 06 May 2009 05:48:20 GMT]]></title><description><![CDATA[<p>der fehler kommt am ende der deklaration von klasse C, da sagt er mir dann das C mehrdeutig ist.</p>
<pre><code class="language-cpp">class C: virtual public B, virtual private D
{
    public:
        C &amp;foo(){/*....*/return *this;};
}; // hier sagt er mir dann &quot;C&quot;: Mehrdeutige Vererbung von &quot;B &amp;A::foo(void)&quot;
</code></pre>
<p>bezüglich des rückgabetyps hab ich gelesen, dass kohärente(abgeleitete) typen auch erlaubt sind, eben wie in meinem beispiel.<br />
A gibt ein A, B ein B, C ein C und D ein D zurück, sie alle beziehen sich aber auf die in A abstrakt definierte methode virtuell A &amp;foo() = 0. so ist es zumindest konzipiert.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1706195</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1706195</guid><dc:creator><![CDATA[StarCraftFeuerteufel]]></dc:creator><pubDate>Wed, 06 May 2009 05:48:20 GMT</pubDate></item><item><title><![CDATA[Reply to wieder spaß mit vererbung :-) on Wed, 06 May 2009 09:27:26 GMT]]></title><description><![CDATA[<p>wenn der name A::foo in B durch B::foo überdeckt wird, hab ich in mal mit using wieder bekannt gemacht. allerdings kennt er jetzt die B:foo(int) nicht mehr.</p>
<pre><code class="language-cpp">//...
class B: virtual public A
{
	public:
		using A::foo;
		B &amp;foo(int para){A::foo();/*....*/ return *this;};
};
//...
int main()
{
	C c;
	c.foo(5); //Fehler
	foo2(c);
	return 0;
};
</code></pre>
<p>Fehler:</p>
<pre><code>error C2660: 'C::foo': Funktion akzeptiert keine 1 Argumente
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1706300</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1706300</guid><dc:creator><![CDATA[StarCraftFeuerteufel]]></dc:creator><pubDate>Wed, 06 May 2009 09:27:26 GMT</pubDate></item><item><title><![CDATA[Reply to wieder spaß mit vererbung :-) on Wed, 06 May 2009 10:18:22 GMT]]></title><description><![CDATA[<p>wie auch. C::foo() überdeckt wieder die geerbten Funktionen.<br />
Lösung: <code>using B::foo(int);</code></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1706335</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1706335</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Wed, 06 May 2009 10:18:22 GMT</pubDate></item><item><title><![CDATA[Reply to wieder spaß mit vererbung :-) on Wed, 06 May 2009 10:18:51 GMT]]></title><description><![CDATA[<p>C::foo() hat ja auch keine Parameter, demenstsprechend spuckt der Compiler dir diesen Fehler aus.</p>
<p>Siehe:</p>
<pre><code class="language-cpp">class C: virtual public B, virtual private D
{
    public:
        C &amp;foo(){/*....*/return *this;}; // &lt;- kain Parameter
};
</code></pre>
<p>Gruß Kimmi</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1706336</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1706336</guid><dc:creator><![CDATA[kimmi]]></dc:creator><pubDate>Wed, 06 May 2009 10:18:51 GMT</pubDate></item><item><title><![CDATA[Reply to wieder spaß mit vererbung :-) on Wed, 06 May 2009 10:35:46 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">using B::foo(int);
</code></pre>
<p>kann schon mal nicht gehen, und geht auch nicht, weil bei using nur die bekanntmachung von namen erlaubt ist, dh. nix mit parameterlisten, man macht damit immer alle methoden mit diesen namen bekannt. einzig zulässig wäre in C</p>
<pre><code class="language-cpp">using B::foo;
</code></pre>
<p>dann hab ich aber das problem, dass er jetzt A::foo() in der methode B::foo(int) nicht kennt</p>
<pre><code>public: virtual class A &amp; __thiscall A::foo(void)&quot; (?foo@A@@UAEAAV1@XZ)&quot; in
Funktion &quot;&quot;public: class B &amp; __thiscall B::foo(int)&quot; (?foo@B@@QAEAAV1@H@Z)&quot;
</code></pre>
<p>also abstrakte methode A::foo() wird ja meines wissens auch erst in C gebunden (späte bindung heißt das wohl), dennoch müsste B sie trotzdem kennen oder zumindest wissen das es eine solche in jeder instanz abgeleiteter nicht abstrakter klassen gibt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1706349</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1706349</guid><dc:creator><![CDATA[StarCraftFeuerteufel]]></dc:creator><pubDate>Wed, 06 May 2009 10:35:46 GMT</pubDate></item><item><title><![CDATA[Reply to wieder spaß mit vererbung :-) on Thu, 07 May 2009 05:41:50 GMT]]></title><description><![CDATA[<p>also mir ist noch nicht ganz klar warum ich die virtuals bei C weglassen kann, da ich dann zweimal Basisklasse A habe.<br />
allerdings kann ich bei B und D die virtuals weglassen, wobei er mit dann sagt, dass der rückgabetyp von foo in der klass C nicht mehr kovariant ist, das verstehe ich allerdings nicht, da B und D doch beide von A abgeleitet sind.<br />
ich bin da jetzt leider etwas verwirrt und komme an diesem punkt nicht weiter.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1706858</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1706858</guid><dc:creator><![CDATA[StarCraftFeuerteufel]]></dc:creator><pubDate>Thu, 07 May 2009 05:41:50 GMT</pubDate></item><item><title><![CDATA[Reply to wieder spaß mit vererbung :-) on Thu, 07 May 2009 06:03:00 GMT]]></title><description><![CDATA[<p>Dann shcau dir am Besten nochmal den Abschnitt zur virtuellen Vererbung im buch deiner Wahl an. Die Klassen, die von der gemeinsamen Basisklasse erben (also in deinem Fall B und D) müssen virtuell von der Basis erben. Die Klasse, die wieder alle Eigenschaften in sich vereint (C) muss nicht virtuell erben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1706866</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1706866</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Thu, 07 May 2009 06:03:00 GMT</pubDate></item><item><title><![CDATA[Reply to wieder spaß mit vererbung :-) on Thu, 07 May 2009 08:49:53 GMT]]></title><description><![CDATA[<p>ahh sorry, stimmt natürlich, hab ich verwechselt. wenn ich allerdings C für weitere vererbungen vorsehe, sollten die virtuals bestehen bleiben oder?<br />
naja, das ändert allerdings nichts am bestehenden problem. using hilft wie gesagt nicht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1706935</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1706935</guid><dc:creator><![CDATA[StarCraftFeuerteufel]]></dc:creator><pubDate>Thu, 07 May 2009 08:49:53 GMT</pubDate></item><item><title><![CDATA[Reply to wieder spaß mit vererbung :-) on Thu, 07 May 2009 14:29:37 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">A::foo()
</code></pre>
<p>Ruft explizit die Function <code>foo</code> von <code>A</code> auf, da wird also keine Polymorphie oder sowas angewendet. Nun ist die Funktion <code>foo</code> in <code>A</code> abstrakt, also hat sie keine definition, wodurch der Linker meckert. Wenn du die überschriebene Funktion aufrufen willst, dann musst du <code>foo</code> unqualifiziert aufrufen.</p>
<p>Und wegen der Mehrdeutigkeit:<br />
Das scheint ein Problem mit dem Rückgabewert zu sein. Der Kompiler erkennt nicht, dass <code>C&amp; foo()</code> die gleiche Funktion überschreibt wie <code>B&amp; foo()</code> und <code>D&amp; foo()</code> . Wenn du in den Klasse B und D den Rückgabewert auf A&amp; änderst, dann funktioniert es. Keine Ahnung wie der Standard dazu genau lautet und wo jetzt das Problem liegt. Also ob es der Standard so definiert oder der Kompiler hier einen Fehler macht.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1707185</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1707185</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Thu, 07 May 2009 14:29:37 GMT</pubDate></item><item><title><![CDATA[Reply to wieder spaß mit vererbung :-) on Thu, 07 May 2009 16:52:02 GMT]]></title><description><![CDATA[<p>also das mit der mehrdeutigkeit hat sich erledigt, das kommt ja nur wenn ich das mit using machen würde.<br />
wenn ich jetzt aber in B statt A::foo nur foo schreibe, meckert er halt rum das foo keine 0 Parameter akzeptiert, obwohl es ja noch die abstrakte methode von A gibt, die natürlich erst in späteren abgeleiteten klassen definiert wird (das ist ja der sinn der abstrakten methoden).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1707292</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1707292</guid><dc:creator><![CDATA[StarCraftFeuerteufel]]></dc:creator><pubDate>Thu, 07 May 2009 16:52:02 GMT</pubDate></item><item><title><![CDATA[Reply to wieder spaß mit vererbung :-) on Thu, 07 May 2009 18:15:29 GMT]]></title><description><![CDATA[<p>Der folgende Code kompiliert bei mir einwandfrei unter VC2008.</p>
<pre><code class="language-cpp">class A 
{ 
public: 
	virtual A &amp;foo() = 0; 
}; 

class B: virtual public A 
{ 
public: 
	A &amp;foo(){foo();/*....*/ return *this; };         // &lt;- einmal A&amp; statt B&amp;
	B &amp;foo(int para){foo();/*....*/ return *this;}; 
};

class D: virtual public A 
{ 
public: 
	A &amp;foo(){/*....*/return *this;};                 // &lt;- einmal A&amp; statt D&amp;
}; 

class C: public B, private D 
{ 
public: 
	C &amp;foo(){/*....*/return *this;}; 
}; 

void foo2(B &amp;b) 
{ 
	b.foo(); 
}; 

int main() 
{ 
	C c; 
	c.foo(); 
	foo2(c); 

	return 0; 
};
</code></pre>
<p>Was ist bei deinem noch anders, so dass er nicht kompiliert?</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1707376</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1707376</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Thu, 07 May 2009 18:15:29 GMT</pubDate></item><item><title><![CDATA[Reply to wieder spaß mit vererbung :-) on Fri, 08 May 2009 07:34:54 GMT]]></title><description><![CDATA[<p>das kompiliert bei mir auch, nur das halt bei B und D die rückgabetypen nicht stimmen. die sollten eigentlich schon B bzw D objekte sein, damit ich auch mit den methoden von B und D arbeiten kann und nicht nur mit denen von A. und wegen der kovarianz sollte das auch möglich sein, aber offensichtlich hakt es ja doch irgendwo. und ich würde halt gern verstehen wollen wo.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1707538</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1707538</guid><dc:creator><![CDATA[StarCraftFeuerteufel]]></dc:creator><pubDate>Fri, 08 May 2009 07:34:54 GMT</pubDate></item><item><title><![CDATA[Reply to wieder spaß mit vererbung :-) on Fri, 08 May 2009 11:03:04 GMT]]></title><description><![CDATA[<p>ok, problem gelöst.<br />
danke für die zahlreichen lösungsvorschläge.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1707691</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1707691</guid><dc:creator><![CDATA[StarCraftFeuerteufel]]></dc:creator><pubDate>Fri, 08 May 2009 11:03:04 GMT</pubDate></item><item><title><![CDATA[Reply to wieder spaß mit vererbung :-) on Fri, 08 May 2009 11:33:36 GMT]]></title><description><![CDATA[<p>FreakyBKA schrieb:</p>
<blockquote>
<p>ok, problem gelöst.<br />
danke für die zahlreichen lösungsvorschläge.</p>
</blockquote>
<p>Würdest du uns auch verraten wie? Wollte mich gerade durch den Standard wühlen, um herauszufinden, was der Standard dazu genau sagt.<br />
Oder hast du dein Problem anders gelöst?</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1707709</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1707709</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Fri, 08 May 2009 11:33:36 GMT</pubDate></item><item><title><![CDATA[Reply to wieder spaß mit vererbung :-) on Sun, 10 May 2009 09:29:28 GMT]]></title><description><![CDATA[<p>ist glaub ich die kombination einiger lösungsvorschläge, und hat wahrscheinlich nur wegen meinem unverständnis so lange gedauert <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>
<pre><code class="language-cpp">class A
{
	public:
		void a(){};
		virtual A &amp;foo() = 0;
};

class B: virtual public A
{
	public:
		void b(){};
//hier stand ja mal A::foo drin, was wegen dem direkten aufruf falsch ist
		virtual B &amp;foo(int para) {foo(); b(); return *this;};
//hier wird A::foo wieder sichtbar gemacht
		using A::foo;
};

class D: virtual public A
{
	public:
		void d(){};
		D &amp;foo() {d(); return *this;};
};

class C: virtual public B, virtual public D
{
	public:
		void c(){};
		C&amp; foo(){d(); return *this;};
//dieses using wurde auch mal vorgeschlagen nur als using B::foo(int) oder so
//damit kann man jetzt auch bei C foo(int) aufrufen
		using B::foo;
};

void foo2(B &amp;b)
{
	b.b();
	b.foo();
	b.foo(5);
};

int main()
{
	C c;
	c.foo();
	c.foo(5);
	foo2(c);
	return 0;
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1708390</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1708390</guid><dc:creator><![CDATA[StarCraftFeuerteufel]]></dc:creator><pubDate>Sun, 10 May 2009 09:29:28 GMT</pubDate></item></channel></rss>