<?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[[c++] Problem bei Funktionsaufruf aus Klasse]]></title><description><![CDATA[<p>Hallo Leute,<br />
ich hab mal wieder ein Problem... <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>
<p>Ich habe aus einer Bibliothek 2 Klassen die sich jeweils aus 2 Basisklassen ableiten. Hier die Hierachie:</p>
<p>1. GABin2DecGenome : public GA1DBinaryStringGenome : public GABinaryStringGenome, public GAGenome<br />
2. GARealGenome : GAReal : public GA1DArryAllelGenome : public GA1dArryGenome : public GAArray&lt;T&gt;, public GAGenome</p>
<p>Ich habe nun über eine Abfrage ein Objekt &quot;genome&quot; wie folgt erzeugt:</p>
<pre><code class="language-cpp">GAGenome *genome = NULL;
switch(genometyp) {
	case 1 : genome = new GABin2DecGenome(map, objective); break;
	case 2 : genome = new GARealGenome(alleles, objective); break;
}
</code></pre>
<p>Funktioniert auch wunderbar.<br />
Ich möchte nun im weiteren Code mittels einer weiteren Abfrage auf die Funktion &quot;float phenotype(unsigned int n) const&quot; der Klasse GABin2DecGenome auf das Objekt genome anwenden. Dazu habe ich folgende Abfrage geschrieben:</p>
<pre><code class="language-cpp">if (genometyp ==1){

*genome = ga-&gt;population().individual(0);  
cout &lt;&lt; genome-&gt;phenotype(0);
}
</code></pre>
<p>Es wird folgender Fehler ausgegeben :</p>
<pre><code>`phenotype' undeclared (first use this function)
</code></pre>
<p>Ich denk mal, dass es daran liegt das es keine Funktion der Basisiklasse ist, oder? Wie bekomme ich das trotzdem hin? Ich dachte er berücksichtigt das garnicht, wenn die Schleife mit genometyp == 1 abgefragt wird ist das Objekt genome aus der Klasse GABin2Dec und damit die Funktion anwendbar, oder nicht?</p>
<p>Viele Grüße</p>
<p>Guddy</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/220286/c-problem-bei-funktionsaufruf-aus-klasse</link><generator>RSS for Node</generator><lastBuildDate>Wed, 07 Oct 2026 09:55:12 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/220286.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 14 Aug 2008 09:20:31 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to [c++] Problem bei Funktionsaufruf aus Klasse on Thu, 14 Aug 2008 09:20:31 GMT]]></title><description><![CDATA[<p>Hallo Leute,<br />
ich hab mal wieder ein Problem... <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>
<p>Ich habe aus einer Bibliothek 2 Klassen die sich jeweils aus 2 Basisklassen ableiten. Hier die Hierachie:</p>
<p>1. GABin2DecGenome : public GA1DBinaryStringGenome : public GABinaryStringGenome, public GAGenome<br />
2. GARealGenome : GAReal : public GA1DArryAllelGenome : public GA1dArryGenome : public GAArray&lt;T&gt;, public GAGenome</p>
<p>Ich habe nun über eine Abfrage ein Objekt &quot;genome&quot; wie folgt erzeugt:</p>
<pre><code class="language-cpp">GAGenome *genome = NULL;
switch(genometyp) {
	case 1 : genome = new GABin2DecGenome(map, objective); break;
	case 2 : genome = new GARealGenome(alleles, objective); break;
}
</code></pre>
<p>Funktioniert auch wunderbar.<br />
Ich möchte nun im weiteren Code mittels einer weiteren Abfrage auf die Funktion &quot;float phenotype(unsigned int n) const&quot; der Klasse GABin2DecGenome auf das Objekt genome anwenden. Dazu habe ich folgende Abfrage geschrieben:</p>
<pre><code class="language-cpp">if (genometyp ==1){

*genome = ga-&gt;population().individual(0);  
cout &lt;&lt; genome-&gt;phenotype(0);
}
</code></pre>
<p>Es wird folgender Fehler ausgegeben :</p>
<pre><code>`phenotype' undeclared (first use this function)
</code></pre>
<p>Ich denk mal, dass es daran liegt das es keine Funktion der Basisiklasse ist, oder? Wie bekomme ich das trotzdem hin? Ich dachte er berücksichtigt das garnicht, wenn die Schleife mit genometyp == 1 abgefragt wird ist das Objekt genome aus der Klasse GABin2Dec und damit die Funktion anwendbar, oder nicht?</p>
<p>Viele Grüße</p>
<p>Guddy</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1564547</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1564547</guid><dc:creator><![CDATA[guddy]]></dc:creator><pubDate>Thu, 14 Aug 2008 09:20:31 GMT</pubDate></item><item><title><![CDATA[Reply to [c++] Problem bei Funktionsaufruf aus Klasse on Thu, 14 Aug 2008 09:55:40 GMT]]></title><description><![CDATA[<p>guddy schrieb:</p>
<blockquote>
<p>Ich denk mal, dass es daran liegt das es keine Funktion der Basisiklasse ist, oder?</p>
</blockquote>
<p>Korrekt.</p>
<p>guddy schrieb:</p>
<blockquote>
<p>Wie bekomme ich das trotzdem hin?</p>
</blockquote>
<p>Du könntest einen <code>dynamic_cast</code> anwenden:</p>
<pre><code class="language-cpp">GABin2DecGenome* bin2DecGenome = dynamic_cast&lt;GABin2DecGenome*&gt;(genome);

if(bin2DecGenome) // Zeiger gültig?
{
  /* erfolgreich */
}
</code></pre>
<p>Ich möchte aber noch darauf hinweisen, dass <code>dynamic_cast</code> meistens auf einen Designfehler hinweist. Es gibt Ausnahmen, wo man den Cast benötigt, aber eigentlich höchst selten bis nie.<br />
In deinem Fall wäre es vielleicht eine Überlegung wert die Funktion zu zerstückeln. Eine wenn ein GABin2DecGenome Objekt kommt und eine für das GARealGenome Objekt. Wenn Methoden aus der Basisklasse aufgerufen werden, welche beide Objekte betreffen würde, kann man dafür gemeinsame Funktionen erstellen. Also irgendwie so:</p>
<pre><code class="language-cpp">void first(GABin2DecGenome* genome)
{
  /* Irgendwas spezielles */

  all(genome);

  /* wieder was eigenes */

  /* wieder eine allgemeine Funktion? */
}

void second(GARealGenome* genome)
{
  all(genome);

  /* oder eine andere Reihenfolge, das Prinzip sollte klar sein ;) */
}

void all(GAGenome* genome)
{
  /* Irgendwas */
}

// Irgendwo:
switch(genometyp) {
    case 1 : first(new GABin2DecGenome(map, objective)); break;
    case 2 : second(new GARealGenome(alleles, objective)); break;
}
</code></pre>
<p>Das ist aber nur ein sehr grobes Beispiel, welches das Prinzip verraten soll.</p>
<p>guddy schrieb:</p>
<blockquote>
<p>Ich dachte er berücksichtigt das garnicht, wenn die Schleife mit genometyp == 1 abgefragt wird ist das Objekt genome aus der Klasse GABin2Dec und damit die Funktion anwendbar, oder nicht?</p>
</blockquote>
<p>1. Ist das keine Schleife, sondern eine If-Anweisung.<br />
2. Es gibt keinen Zusammenhang zwischen dem Wert <code>genometyp</code> und dem Objekt auf welches der Zeiger <code>genome</code> zeigt. Und <code>genome</code> zeigt ganz klar auf ein Objekt der Basisklasse und nichts anderes.<br />
3. Würde der Compiler dem Standard widersprechen, wenn er das durchgehen lassen würde.</p>
<p>guddy schrieb:</p>
<blockquote>
<pre><code class="language-cpp">if (genometyp ==1){
 
*genome = ga-&gt;population().individual(0); // (1)
cout &lt;&lt; genome-&gt;phenotype(0);
}
</code></pre>
</blockquote>
<p>Mir gefällt da aber vor allem diese Zeile (1) nicht. Bist du dir bewusst was du da machst? Du kopierst nur den GAGenome Teil vom Wert, welcher <code>ga-&gt;population().individual(0)</code> zurückgibt und der Rest wird nicht kopiert. Es wird somit nur eine Teilkopie ausgeführt.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1564569</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1564569</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Thu, 14 Aug 2008 09:55:40 GMT</pubDate></item><item><title><![CDATA[Reply to [c++] Problem bei Funktionsaufruf aus Klasse on Thu, 14 Aug 2008 10:42:52 GMT]]></title><description><![CDATA[<p>Hi,<br />
bin bis jetzt noch über keinen Fall gelaufen wo man den dynamic_cast gebraucht hätte. Kannst du mir ein Beispiel dafür geben, wo du ihn wirklich gebraucht hast?</p>
<p>Gruß Andy</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1564603</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1564603</guid><dc:creator><![CDATA[Andy2211]]></dc:creator><pubDate>Thu, 14 Aug 2008 10:42:52 GMT</pubDate></item><item><title><![CDATA[Reply to [c++] Problem bei Funktionsaufruf aus Klasse on Thu, 14 Aug 2008 11:31:15 GMT]]></title><description><![CDATA[<p>Andy2211 schrieb:</p>
<blockquote>
<p>bin bis jetzt noch über keinen Fall gelaufen wo man den dynamic_cast gebraucht hätte. Kannst du mir ein Beispiel dafür geben, wo du ihn wirklich gebraucht hast?</p>
</blockquote>
<p>... ehm ... auf Anhieb ... nein <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="🙂"
    /><br />
Ich habe ihn glaub ich ein einziges Mal wirklich eingesetzt, als ich auch eine Basisklasse hatte und genau wusste, von welchem Typ das Objekt eigentlich ist. Ein <code>static_cast</code> war aber nicht möglich, da der Typ von mehreren Klassen erbte. Aber um ehrlich zu sein, finde ich den Code dazu nicht mehr und ich weiss auch nicht mehr, wieso es dort nicht anders ging. Und wenn ich den Code nicht mehr finde, könnte es fast noch sein, dass ich am Ende doch eine andere Lösung gefunden hatte <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /></p>
<p>Ein Grund, wieso man den <code>dynamic_cast</code> verwenden könnte, wäre vielleicht wegen eine schlecht gemachten Bibliothek. Welche nur ein Basisobjekt aktzeptiert und es irgendwo wieder zurückgibt, man dort aber den abgeleiteten Typ benötigt. Also quasi zur Behebung von Designfehlern von anderen <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="😃"
    /></p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1564629</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1564629</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Thu, 14 Aug 2008 11:31:15 GMT</pubDate></item><item><title><![CDATA[Reply to [c++] Problem bei Funktionsaufruf aus Klasse on Thu, 14 Aug 2008 11:57:54 GMT]]></title><description><![CDATA[<p>Pointer casten tu ich hier den ganzen Tag lang fröhlich, dynamic_cast ist dabei einfach die &quot;sicherste&quot; Option, da es eine Überprüfung zur Laufzeit zur Folge hat und entsprechend sinnvolle Fehlermeldungen gibt, anstatt fröhlich weiter zu rattern.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1564661</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1564661</guid><dc:creator><![CDATA[Fellhuhn]]></dc:creator><pubDate>Thu, 14 Aug 2008 11:57:54 GMT</pubDate></item><item><title><![CDATA[Reply to [c++] Problem bei Funktionsaufruf aus Klasse on Thu, 14 Aug 2008 12:00:13 GMT]]></title><description><![CDATA[<p>Danke Dravere, das hat mich auf jeden Fall weitergebracht.</p>
<blockquote>
<p>Mir gefällt da aber vor allem diese Zeile (1) nicht. Bist du dir bewusst was du da machst? Du kopierst nur den GAGenome Teil vom Wert, welcher ga-&gt;population().individual(0) zurückgibt und der Rest wird nicht kopiert. Es wird somit nur eine Teilkopie ausgeführt.</p>
</blockquote>
<p>Ich denk schon, indvidual() gibt eine Referenz auf ein Objekt der Klasse GAGenome zurück.<br />
Ich möchte ungern die Funktion zerstückeln, da das Programm auch von anderen Usern mit derselben Bibliothek nutzbar seien soll.</p>
<p>Kannst du mir mal den unterschied zwischen statischem und dynamischem cast erklären?</p>
<p>Grüße</p>
<p>Guddy</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1564666</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1564666</guid><dc:creator><![CDATA[guddy]]></dc:creator><pubDate>Thu, 14 Aug 2008 12:00:13 GMT</pubDate></item><item><title><![CDATA[Reply to [c++] Problem bei Funktionsaufruf aus Klasse on Thu, 14 Aug 2008 12:07:57 GMT]]></title><description><![CDATA[<p>Bei <a href="http://www.c-plusplus.net/forum/viewtopic-var-t-is-220251.html" rel="nofollow">diesem Problem</a> habe ich bisher auch keine andere Lösung gefunden als dynamisch zu casten. (Ich schreibe die aktuelle Lösung mit dem dynamischen Cast später noch in den genannten Thread)</p>
<p>Oft kann man dynamische Casts durch statische Ersetzen, weil von vornherein klar ist, welcher Typ vorliegt. Ein Beispiel wäre wieder einmal boost::any ( <code>if (data-&gt;type() == typeid(Class)) { static_cast&lt; Class* &gt; } else { throw bad_any_cast }</code> ).</p>
<p>EDIT:</p>
<p>guddy schrieb:</p>
<blockquote>
<p>Kannst du mir mal den unterschied zwischen statischem und dynamischem cast erklären?</p>
</blockquote>
<p>Der statische Cast erzeugt bereits zur Compilezeit Code zur Umwandlung. Sprich, wenn Du einen Basisklassenzeiger statisch auf den einer abgeleiteten Klasse castest, wird Code erzeugt, der diesen Zeiger u.U. verschiebt (weil Basisobjekt und abgeleitetes Objekt unterschiedliche Startadressen haben können). Im Binärcode steht dann nur noch z.B. <code>neuerzeiger = alterzeiger + 4</code> . Ist dieses Basisobjekt allerdings in Wirklichkeit von einem anderen abgeleiteten Typ, läuft das Programm fröhlich mit einem falschen Zeiger weiter.</p>
<p>Ein dynamischer Cast erzeugt darüberhinaus Code, der zur Laufzeit in einer Tabelle nachschaut, ob das Basisobjekt wirklich von diesem fraglichen abgeleiteten Typ ist, und gibt einen Nullzeiger zurück, falls dem nicht so ist (oder wirft eine Exception, wenn man Referenzen castet).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1564669</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1564669</guid><dc:creator><![CDATA[LordJaxom]]></dc:creator><pubDate>Thu, 14 Aug 2008 12:07:57 GMT</pubDate></item><item><title><![CDATA[Reply to [c++] Problem bei Funktionsaufruf aus Klasse on Thu, 14 Aug 2008 12:19:53 GMT]]></title><description><![CDATA[<p>Ich ändere mal schnell die Reihenfolge deines Satzes Fellhuhn.</p>
<p>Fellhuhn schrieb:</p>
<blockquote>
<p>... dynamic_cast ist dabei einfach die &quot;sicherste&quot; Option, da es eine Überprüfung zur Laufzeit zur Folge hat und entsprechend sinnvolle Fehlermeldungen gibt, anstatt fröhlich weiter zu rattern.</p>
</blockquote>
<p>Das hat niemand hier bestritten, das ist wahr. Wobei die sinnvolle Fehlermeldung auch ein Nullzeiger sein kann, was einen unschönen Absturz zur Folge hat.</p>
<p>Fellhuhn schrieb:</p>
<blockquote>
<p>Pointer casten tu ich hier den ganzen Tag lang fröhlich, ...</p>
</blockquote>
<p>Das dagegen ist eher schlecht. Ein Downcast, also von einer Basisklasse zu einer abgeleiteten Klasse, sollte so gut wie nie vorkommen. Wenn du die ganze Zeit am Casten bist, dann hast du Fehler im Design! Klar ist es nicht verboten, aber meistens eher ungeschickt und teilweise auch Fehleranfällig.</p>
<p>Und noch eine Ergänzung zu LordJaxoms erklärung:<br />
<a href="http://www.c-plusplus.net/forum/viewtopic-var-t-is-39493.html" rel="nofollow">http://www.c-plusplus.net/forum/viewtopic-var-t-is-39493.html</a><br />
<a href="http://www.c-plusplus.net/forum/viewtopic-var-t-is-39463.html" rel="nofollow">http://www.c-plusplus.net/forum/viewtopic-var-t-is-39463.html</a></p>
<p>Zudem, ein <code>static_cast</code> ist nicht möglich, wenn der Typ, zu welchem man casten möchte, mehrere Basisklassen besitzt. Dann muss in jedem Fall <code>dynamic_cast</code> eingesetzt werden.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1564687</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1564687</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Thu, 14 Aug 2008 12:19:53 GMT</pubDate></item><item><title><![CDATA[Reply to [c++] Problem bei Funktionsaufruf aus Klasse on Thu, 14 Aug 2008 13:12:25 GMT]]></title><description><![CDATA[<blockquote>
<p>Zudem, ein static_cast ist nicht möglich, wenn der Typ, zu welchem man casten möchte, mehrere Basisklassen besitzt. Dann muss in jedem Fall dynamic_cast eingesetzt werden.</p>
</blockquote>
<p>Ein static_cast ist in vielen Fällen dann trotzdem möglich. Ein Fall wo es nicht geht ist wenn man virtuelle Basisklassen hat (reicht dann aber schon eine AFAIK). Und ich glaube auch wenn die selbe Klasse in der Hirarchie mehrfach auftaucht (&quot;dreaded diamond&quot; ohne virtuelle Vererbung).<br />
Beim &quot;dreaded diamond&quot; ohne virtuelle Vererbung kann man aber, wenn man weiss welches Unterobjekt man genau hat, mit 2 static_cast arbeiten um dem dynamic_cast zu entkommen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1564734</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1564734</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Thu, 14 Aug 2008 13:12:25 GMT</pubDate></item><item><title><![CDATA[Reply to [c++] Problem bei Funktionsaufruf aus Klasse on Thu, 14 Aug 2008 13:59:50 GMT]]></title><description><![CDATA[<p>Oh, stimmt. Mein Fehler. Ich ziehe meine letzte Aussage zurück <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="🙂"
    /><br />
Und ja, eine virtuelle Basisklasse und es geht nicht mehr (auch gleich mit MSVC 2005 getestet). Und bei dreaded diamond ist das sowieso eine komplexe Sache. Da kann man ja nicht mal einen normalen Upcast durchführen.</p>
<p>Etwas Code für guddy oder andere:</p>
<pre><code class="language-cpp">// virtual base class
class Base
{ };

class Test : public virtual Base
{ }

int main()
{
  Base* base = new Test; // normal.

  // Test* test = static_cast&lt;Test*&gt;(base); geht nicht!
  Test* test = dynamic_cast&lt;Test*&gt;(base); // geht einwandfrei!

  delete test;

  return 0;
}

// dreaded diamond

class Base
{ };

class Derv1 : public Base
{ };

class Derv2 : public Base
{ };

class Test : public Derv1, public Derv2
{ };

int main()
{
  Base* base = static_cast&lt;Test::Derv1*&gt;(new Test); // Lustiger Upcast :)

  // Test* test = static_cast&lt;Test*&gt;(base); geht nicht!
  Test* test = static_cast&lt;Test*&gt;(static_cast&lt;Derv1*&gt;(base)); // geht!

  delete test;

  return 0;
}
</code></pre>
<p>Was eine virtuelle Basisklasse und/oder dreaded diamond genau ist, solltet ihr anderswo nachlesen. Es ist aber wohl eher ein fortgeschrittenes Konzept der Sprache.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1564791</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1564791</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Thu, 14 Aug 2008 13:59:50 GMT</pubDate></item></channel></rss>