<?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[Virtuelle Funktionen in Klasse verursachen Absturz]]></title><description><![CDATA[<p>Hallo,<br />
ich habe eine Basisklasse mit einigen normalen und virtuellen Funktionen. Eine andere Klasse ist von der Basisklasse abgeleitet.<br />
Wenn ich nun die virtuellen Funktionen (egal ob von der neuen Klasse überschrieben oder nicht) aufrufe, verabschiedet sich das Programm.</p>
<p>Verdeutlichung:</p>
<pre><code class="language-cpp">class Basis {
	public:
		virtual void Func1();
		void Func2();
		...
};

class Neu : public Basis {
	...
};

Neu *pNeu = new Neu;

// Das steht natürlich nicht so da, sondern wird über Umwege übergeben:
LPVOID pV = pNeu;
Basis *pBasis = (Basis*)pV; 

pBasis-&gt;Func2(); // Funktioniert
pBasis-&gt;Func1(); // Absturz: &quot;Access violation reading location 0xccccccf0.&quot;
</code></pre>
<p>Ich vermute, man muss den Pointer pNeu irgendwie anders in einen Basis-Pointer (pBasis) umwandeln..</p>
<p>MfG,<br />
Max</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/207796/virtuelle-funktionen-in-klasse-verursachen-absturz</link><generator>RSS for Node</generator><lastBuildDate>Sun, 11 Oct 2026 10:47:19 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/207796.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 11 Mar 2008 20:24:40 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Virtuelle Funktionen in Klasse verursachen Absturz on Wed, 12 Mar 2008 17:08:14 GMT]]></title><description><![CDATA[<p>Hallo,<br />
ich habe eine Basisklasse mit einigen normalen und virtuellen Funktionen. Eine andere Klasse ist von der Basisklasse abgeleitet.<br />
Wenn ich nun die virtuellen Funktionen (egal ob von der neuen Klasse überschrieben oder nicht) aufrufe, verabschiedet sich das Programm.</p>
<p>Verdeutlichung:</p>
<pre><code class="language-cpp">class Basis {
	public:
		virtual void Func1();
		void Func2();
		...
};

class Neu : public Basis {
	...
};

Neu *pNeu = new Neu;

// Das steht natürlich nicht so da, sondern wird über Umwege übergeben:
LPVOID pV = pNeu;
Basis *pBasis = (Basis*)pV; 

pBasis-&gt;Func2(); // Funktioniert
pBasis-&gt;Func1(); // Absturz: &quot;Access violation reading location 0xccccccf0.&quot;
</code></pre>
<p>Ich vermute, man muss den Pointer pNeu irgendwie anders in einen Basis-Pointer (pBasis) umwandeln..</p>
<p>MfG,<br />
Max</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1472381</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1472381</guid><dc:creator><![CDATA[ripmav]]></dc:creator><pubDate>Wed, 12 Mar 2008 17:08:14 GMT</pubDate></item><item><title><![CDATA[Reply to Virtuelle Funktionen in Klasse verursachen Absturz on Tue, 11 Mar 2008 22:02:49 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">class base_foo
{
public:
    virtual void bar_pure_virtual() = 0;
    virtual void bar_virtual() { std::cout &lt;&lt; &quot;base_foo::bar_virtaul&quot; &lt;&lt; std::endl; }
    void bar(){ std::cout &lt;&lt; &quot;base_foo::bar&quot; &lt;&lt; std::endl; }
};

class foo : public base_foo
{
public:
    void bar_pure_virtual() { std::cout &lt;&lt; &quot;foo::bar_pure_virtual&quot; &lt;&lt; std::endl; }
    void bar_virtual() { std::cout &lt;&lt; &quot;foo::bar_virtual&quot; &lt;&lt; std::endl; }
};

int main()
{
    base_foo* ptr_foo = new foo;
    ptr_foo-&gt;bar();
    ptr_foo-&gt;bar_virtual();
    ptr_foo-&gt;bar_pure_virtual();
}
</code></pre>
<p>...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1472400</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1472400</guid><dc:creator><![CDATA[*D*Evil]]></dc:creator><pubDate>Tue, 11 Mar 2008 22:02:49 GMT</pubDate></item><item><title><![CDATA[Reply to Virtuelle Funktionen in Klasse verursachen Absturz on Tue, 11 Mar 2008 21:59:14 GMT]]></title><description><![CDATA[<p>da fehlt</p>
<p>(D)Evil schrieb:</p>
<blockquote>
<p>...<br />
class foo : public base_foo<br />
...</p>
</blockquote>
<p>und was den cast anbelangt, so mach folgendes:</p>
<pre><code class="language-cpp">Basis *pBasis = dynamic_cast&lt;Basis*&gt;(pV);
</code></pre>
<p>--&gt; NULL wenn nicht erfolgreich...<br />
oder gleich</p>
<pre><code class="language-cpp">Basis&amp; pBasis = dynamic_cast&lt;Basis&amp;&gt;(*pV);
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1472442</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1472442</guid><dc:creator><![CDATA[muffmolch]]></dc:creator><pubDate>Tue, 11 Mar 2008 21:59:14 GMT</pubDate></item><item><title><![CDATA[Reply to Virtuelle Funktionen in Klasse verursachen Absturz on Wed, 12 Mar 2008 06:47:25 GMT]]></title><description><![CDATA[<p>Und um auch mal das eigentliche Thema dieses Post anzusprechen: Du darfst einen void-Pointer <strong>nur</strong> in das zurück-casten, was es vorher einmal war. Hier wandelst Du ein Neu* in ein void*, und den dann in ein Basis*. Das sind unterschiedliche Objekte (bzw. unterschiedliche Sichtweisen auf ein Objekt).</p>
<p>In Ordnung wäre</p>
<pre><code class="language-cpp">LPVOID pV = static_cast&lt;Basis*&gt;(pNeu);
Basis *pBasis = static_cast&lt;Basis*&gt;(pV);
</code></pre>
<p>Noch besser wäre, den void-Zeiger ganz zu vermeiden <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/1472518</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1472518</guid><dc:creator><![CDATA[LordJaxom]]></dc:creator><pubDate>Wed, 12 Mar 2008 06:47:25 GMT</pubDate></item><item><title><![CDATA[Reply to Virtuelle Funktionen in Klasse verursachen Absturz on Wed, 12 Mar 2008 07:44:23 GMT]]></title><description><![CDATA[<p>Hat der Pointertyp nicht nur zur Compilezeit &quot;kosmetische&quot; Effekte? Der ist doch immer identisch, egal worauf es zeigt. Da dürfte es doch egal sein auf was für einen Pointer wie und warum gecastet wird, solange die Daten dort in Ordnung sind, oder nicht?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1472542</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1472542</guid><dc:creator><![CDATA[Fellhuhn]]></dc:creator><pubDate>Wed, 12 Mar 2008 07:44:23 GMT</pubDate></item><item><title><![CDATA[Reply to Virtuelle Funktionen in Klasse verursachen Absturz on Wed, 12 Mar 2008 07:53:06 GMT]]></title><description><![CDATA[<p>Fellhuhn schrieb:</p>
<blockquote>
<p>Hat der Pointertyp nicht nur zur Compilezeit &quot;kosmetische&quot; Effekte? Der ist doch immer identisch, egal worauf es zeigt. Da dürfte es doch egal sein auf was für einen Pointer wie und warum gecastet wird, solange die Daten dort in Ordnung sind, oder nicht?</p>
</blockquote>
<p>Nein, der Base-Zeiger zeigt nur auf ein Base, der Neu-Zeiger zeigt auf ein Neu, welches ein Base als Bestandteil hat. Gerade wenn Polymorphie ins Spiel kommt müssen das <strong>nicht</strong> identische Adressen sein.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1472546</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1472546</guid><dc:creator><![CDATA[LordJaxom]]></dc:creator><pubDate>Wed, 12 Mar 2008 07:53:06 GMT</pubDate></item><item><title><![CDATA[Reply to Virtuelle Funktionen in Klasse verursachen Absturz on Wed, 12 Mar 2008 07:55:23 GMT]]></title><description><![CDATA[<p>Ah, du meinst bei dem Cast zum Base-Pointer wird dieser zB höher gesetzt um etwaige vtables oder was auch immer zu überspringen? Das wäre ja richtig schlecht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1472549</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1472549</guid><dc:creator><![CDATA[Fellhuhn]]></dc:creator><pubDate>Wed, 12 Mar 2008 07:55:23 GMT</pubDate></item><item><title><![CDATA[Reply to Virtuelle Funktionen in Klasse verursachen Absturz on Wed, 12 Mar 2008 08:07:54 GMT]]></title><description><![CDATA[<p>Warum sollte das schlecht sein?</p>
<p>Oder aus der anderen Richtung gefragt: Wie würdest Du es sonst machen? <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="😉"
    /> Spätestens bei Mehrfachvererbung muss ich ein abgeleitetes Objekt sowohl in ein Basis1-Objekt als auch in ein Basis2-Objekt umwandeln können. Die können nicht dieselbe Adresse haben (jedenfalls kann ich mir keinen effizienten Mechanismus vorstellen, der das realisieren könnte).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1472556</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1472556</guid><dc:creator><![CDATA[LordJaxom]]></dc:creator><pubDate>Wed, 12 Mar 2008 08:07:54 GMT</pubDate></item><item><title><![CDATA[Reply to Virtuelle Funktionen in Klasse verursachen Absturz on Wed, 12 Mar 2008 08:28:16 GMT]]></title><description><![CDATA[<p>Ich war nie ein Freund der Mehrfachvererbung. <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/1472572</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1472572</guid><dc:creator><![CDATA[Fellhuhn]]></dc:creator><pubDate>Wed, 12 Mar 2008 08:28:16 GMT</pubDate></item><item><title><![CDATA[Reply to Virtuelle Funktionen in Klasse verursachen Absturz on Wed, 12 Mar 2008 10:24:57 GMT]]></title><description><![CDATA[<p>bei komposition würdest du doch auch nie auf die idee kommen, den zeiger auf ein objekt direkt auf einen zeiger auf ein subobjekt zu verbiegen, oder?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1472643</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1472643</guid><dc:creator><![CDATA[queer_boy]]></dc:creator><pubDate>Wed, 12 Mar 2008 10:24:57 GMT</pubDate></item><item><title><![CDATA[Reply to Virtuelle Funktionen in Klasse verursachen Absturz on Wed, 12 Mar 2008 10:26:53 GMT]]></title><description><![CDATA[<p>Ich hab mir das immer bisher so gedacht das das Basisobjekt an der Adresse liegt auf den der Pointer zeigt und alles zusätzliche der ableitenden Klasse dahinter. Aber das funktioniert natürlich nicht bei Mehrfachvererbung.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1472644</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1472644</guid><dc:creator><![CDATA[Fellhuhn]]></dc:creator><pubDate>Wed, 12 Mar 2008 10:26:53 GMT</pubDate></item><item><title><![CDATA[Reply to Virtuelle Funktionen in Klasse verursachen Absturz on Wed, 12 Mar 2008 10:52:17 GMT]]></title><description><![CDATA[<p>Das hast du dir so gedacht, und das <em>koennte</em> auch eine der moeglichen Implementierungen sein, allerdings ist das afaik im Standard nicht festgelegt, in welcher Reihenfolge Subobjekte im Speicher abgelegt werden. Des weiteren ist im Standard weder festgelegt, wie ein Pointer auszusehen hat, noch ob Pointer auf zwei verschiedene Typen aehnlich oder unterschiedlich auszusehen haben. Da der Standard keinerlei Annahmen treffen kann, wie &quot;ungewoehnlich&quot; die Hardware, das Betriebssystem und das Speichermanagement deiner Plattform sind, huetet er sich davor, solche Konvertierungen wie Derived* -&gt; void* -&gt; Base* allgemein gueltig zu machen.</p>
<p>Uebrigens: da du, ripmav, offensichtlich auch abgeleitete Objekte ueber einen Pointer auf die Basisklasse zerstoeren willst, hast du doch hoffentlich auch den Destruktor der Basisklasse virtuell gemacht, oder? (Das gibt sonst den Alptraum eines jeden Porgrammierers: undefiniertes Verhalten)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1472675</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1472675</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Wed, 12 Mar 2008 10:52:17 GMT</pubDate></item><item><title><![CDATA[Reply to Virtuelle Funktionen in Klasse verursachen Absturz on Wed, 12 Mar 2008 17:04:29 GMT]]></title><description><![CDATA[<p>Hallo,<br />
danke für die vielen Antworten!<br />
Ich muss leider zu einem void-Pointer konvertieren, da die einzige Möglichkeit, einen Pointer zu übermitteln, in einer WinAPI Funktion liegt, und die nimmt nur void-Pointer an..<br />
Ich habe mir jetzt mal die verschiedenen casts angeschaut, und so wie es aussieht, muss ich dynamic_cast verwenden (Wenn ich Neu* zu Basis* konevrtieren will). Das Problem dabei ist, dass der Compiler (MS VC++ 2005) meckert: 'LPVOID' : invalid expression type for dynamic_cast<br />
So wie es aussieht, kann man dynamic_cast nicht mit void* verwenden..<br />
Was sollte ich stattdessen tun? static_cast nehmen? oder gleich reinterpret_cast (dürfte in diesem Fall dieselbe Wirkung wie (Basis*)pV haben) ?</p>
<p>Ich habe mal den Beispielcode meines ersten Posts kompiliert und der Absturz kommt gar nicht.. So wie es aussieht tritt der Fehler entweder nur unter bestimmten Vorraussetzungen auf, oder es liegt gar nicht daran, wie der Pointer konvertiert wird.. Ich werde das nochmal durchtesten..</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/9960">@pumuckl</a>:<br />
Ich brauche in meiner Klasse keinen eigenen Desktruktor, deshalb habe ich den vom System gelassen.. Das dürfte OK sein, oder?</p>
<p>MfG,<br />
Max</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1473139</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1473139</guid><dc:creator><![CDATA[ripmav]]></dc:creator><pubDate>Wed, 12 Mar 2008 17:04:29 GMT</pubDate></item><item><title><![CDATA[Reply to Virtuelle Funktionen in Klasse verursachen Absturz on Wed, 12 Mar 2008 17:37:40 GMT]]></title><description><![CDATA[<p>Wenn du void* zur Übergabe benutzen musst, solltest du immer darauf achten, dass der (statische) Typ das Zeigers vor der Konvertierung in void* identisch mit dem ist, in den du später zurückkonvertierst. Das ist (im Wesentlichen) die einzige Garantie, die der Konvertierung in void* anhaftet - im Allgemeinen (es gibt ein paar wenige zusätzliche Garantien bei primitiven Typen, aber das kann uns hier egal sein) besteht keine bestimmte Beziehung zwischen Zeigerkonvertierungen der Form T* -&gt; U* und T* -&gt; void* -&gt; U*.<br />
Dann sollte alles gut gehen - versuch niemals, solche Probleme durch Probieren mit exotischen Casts zu lösen, selbst wenn es dann gelegentlich zu funktionieren scheint, ist es wahrscheinlich trotzdem falsch. Nebenbei: reinterpret_cast ist immer falsch - es sei denn, du weist genau, was dabei passiert.</p>
<pre><code class="language-cpp">// Das steht natürlich nicht so da, sondern wird über Umwege übergeben:
LPVOID pV = pNeu;
</code></pre>
<p>hier ist der statische Typ Neu* die Konvertierung zurück muss daher ebenfalls zu Neu* erfolgen. Falls du nur garantieren kannst, dass ein Zeiger auf Basis* übergeben wird, muss zunächst in diesen Typen konvertiert werden.</p>
<pre><code class="language-cpp">Neu *pNeu = new Neu;
void* some_func(void*);

Basis *pTmp = pNeu; // implizit
Basis* pBasis = static_cast&lt;Basis*&gt;( some_func( pTmp ) ); // die Konvertierung aus void* bedarf eines Castes
</code></pre>
<p>Falls du auf die Hilfsvariable verzichten willst, kannst du notfalls auch explizit casten - da es allerdings kein äquivalentes implicit_cast gibt, wäre ein static_cast notwendig, was eigentlich zu schweres Geschütz ist. Hilfsweise kann man auch so etwas einsetzen</p>
<pre><code class="language-cpp">template&lt;typename T, typename U&gt;
T implicit_cast(U u) { return u; }
...
Basis* pBasis = static_cast&lt;Basis*&gt;( some_func( implicit_cast&lt;Basis*&gt;( pNeu ) ) );
</code></pre>
<p>Das ist vorteilhaft, indem es einerseits explizit klarstellt, mit welchem Typen gearbeitet wird, und andererseits dies nicht auf einer potentiell gefährlichen syntaktischen Form (=Cast) beruht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1473166</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1473166</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Wed, 12 Mar 2008 17:37:40 GMT</pubDate></item><item><title><![CDATA[Reply to Virtuelle Funktionen in Klasse verursachen Absturz on Wed, 12 Mar 2008 19:11:27 GMT]]></title><description><![CDATA[<p>Hallo,<br />
ich habe jetzt mal campers Methode ausprobiert - hat den Absturz aber leider nicht beseitigt..</p>
<p>Inzwischen habe ich herausgefunden, dass es nicht an einem falsch konvertierten Pointer liegt, da das Problem auch auftritt, wenn ich statt der Klasse Neu die Basisklasse übergebe (also Basis* -&gt; void* -&gt; Basis*).</p>
<p>Das Problem habe ich jetzt mal im WinAPI Forum genauer erklärt, weil es nicht mehr zum Forumteil C++ gehört:<br />
<a href="http://www.c-plusplus.net/forum/viewtopic-var-p-is-1473218.html" rel="nofollow">http://www.c-plusplus.net/forum/viewtopic-var-p-is-1473218.html</a></p>
<p>Danke für die Antworten! Nun kenne ich mich (zumindestens grundlegend) mit casts 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>
<p>MfG,<br />
Max</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1473220</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1473220</guid><dc:creator><![CDATA[ripmav]]></dc:creator><pubDate>Wed, 12 Mar 2008 19:11:27 GMT</pubDate></item></channel></rss>