<?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[derived* -&amp;gt; void* -&amp;gt; base*]]></title><description><![CDATA[<pre><code class="language-cpp">class base { };
class derived : public base { };

derived* a_derived = new derived();

// dann folgt eine übergabe an ein c-api (lua userdata)
void* a_void = a_derived;

// ...und kommt irgendwann wieder als void* zurück
base* a_base = reinterpret_cast&lt;a_base*&gt;(a_void);
</code></pre>
<p>ich bin mir nicht sicher: darf man derived* nach void* und dieses void* nach base* casten?<br />
ich habe ein problem mit einer zerbröselten vtable und vermute hier das problem.<br />
wie siehts aus bei derived* -&gt; void* -&gt; derived*?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/197658/derived-gt-void-gt-base</link><generator>RSS for Node</generator><lastBuildDate>Mon, 29 Jun 2026 21:57:10 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/197658.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 13 Nov 2007 11:06:20 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to derived* -&amp;gt; void* -&amp;gt; base* on Tue, 13 Nov 2007 11:06:20 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">class base { };
class derived : public base { };

derived* a_derived = new derived();

// dann folgt eine übergabe an ein c-api (lua userdata)
void* a_void = a_derived;

// ...und kommt irgendwann wieder als void* zurück
base* a_base = reinterpret_cast&lt;a_base*&gt;(a_void);
</code></pre>
<p>ich bin mir nicht sicher: darf man derived* nach void* und dieses void* nach base* casten?<br />
ich habe ein problem mit einer zerbröselten vtable und vermute hier das problem.<br />
wie siehts aus bei derived* -&gt; void* -&gt; derived*?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1402395</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1402395</guid><dc:creator><![CDATA[luauser]]></dc:creator><pubDate>Tue, 13 Nov 2007 11:06:20 GMT</pubDate></item><item><title><![CDATA[Reply to derived* -&amp;gt; void* -&amp;gt; base* on Tue, 13 Nov 2007 11:25:53 GMT]]></title><description><![CDATA[<p>Du darfst derived* nach void* und wieder zurück casten - das geht ohne Probleme. Der direkte Übergang derived* nach base* ist auch problemlos möglich (sogar ohne Cast). Der indirekte Weg ist aber (hmm) gefährlich, weil eventuelle Adressanpassungen nicht möglich sind.</p>
<p>(bei Mehrfachableitung unterscheidet sich womöglich die Adresse des Gesamtobjekts von der Adresse des Basisanteils - bei der direkten Umwandlung wird dieser Unterschied berücksichtigt, bei deinem indirekten Weg nicht)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1402406</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1402406</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Tue, 13 Nov 2007 11:25:53 GMT</pubDate></item><item><title><![CDATA[Reply to derived* -&amp;gt; void* -&amp;gt; base* on Tue, 13 Nov 2007 13:47:54 GMT]]></title><description><![CDATA[<p>Hallo,<br />
den cast von derived* nach void* solltest du über einen dynamic_cast erledigen.</p>
<pre><code class="language-cpp">void* a_void = dynamic_cast&lt;void*&gt;(a_derived);
</code></pre>
<p>So stellst du sicher, dass a_void auf das vollständige Objekt verweist, was den Cast von a_void nach Base wiederum unproblematisch macht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1402496</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1402496</guid><dc:creator><![CDATA[HumeSikkins]]></dc:creator><pubDate>Tue, 13 Nov 2007 13:47:54 GMT</pubDate></item><item><title><![CDATA[Reply to derived* -&amp;gt; void* -&amp;gt; base* on Tue, 13 Nov 2007 15:22:22 GMT]]></title><description><![CDATA[<p>HumeSikkins schrieb:</p>
<blockquote>
<p>Hallo,<br />
den cast von derived* nach void* solltest du über einen dynamic_cast erledigen.<br />
[...]<br />
So stellst du sicher, dass a_void auf das vollständige Objekt verweist, was den Cast von a_void nach Base wiederum unproblematisch macht.</p>
</blockquote>
<p>gilt das generell oder nur für mein kleines beispiel? denn der void*-pointer wird im konkreten fall x-mal rumgereicht, unter anderem in eine c-bibliothek. woher nimmt der compiler dann die information, dass und wie nach base* gecastet werden kann?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1402570</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1402570</guid><dc:creator><![CDATA[luauser]]></dc:creator><pubDate>Tue, 13 Nov 2007 15:22:22 GMT</pubDate></item><item><title><![CDATA[Reply to derived* -&amp;gt; void* -&amp;gt; base* on Tue, 13 Nov 2007 15:28:13 GMT]]></title><description><![CDATA[<p>Das gilt noch nicht einmal generell, das ist einfach nur Unsinn - aus dem void-Pointer kann der Compiler nicht einmal ableiten, was wirklich dahinter steht - und er kann auch bei der Umwandlung (egal ob ohne oder mit dynamic_cast&lt;&gt;) nicht wissen, welche Adresse später tatsächlich gebraucht wird (und was das &quot;vollständige Objekt&quot; eigentlich ist.</p>
<p>Du mußt dir schon selber merken, was für einen Typ du da als void* übergeben hast - und später genau in diesen Typ zurückwandeln:</p>
<pre><code class="language-cpp">//C-Funktionen als Minimalbeispiel
void set_data(void* ptr);
coid* get_data();

//Anwendung
derived* pDer = new derived;
set_data(pDer);
...
derived* ptr2 = (derived*)get_data();
base* pBas = ptr2;
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1402576</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1402576</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Tue, 13 Nov 2007 15:28:13 GMT</pubDate></item><item><title><![CDATA[Reply to derived* -&amp;gt; void* -&amp;gt; base* on Tue, 13 Nov 2007 15:45:31 GMT]]></title><description><![CDATA[<p>CStoll schrieb:</p>
<blockquote>
<p>Das gilt noch nicht einmal generell, das ist einfach nur Unsinn - aus dem void-Pointer kann der Compiler nicht einmal ableiten, was wirklich dahinter steht - und er kann auch bei der Umwandlung (egal ob ohne oder mit dynamic_cast&lt;&gt;) nicht wissen, welche Adresse später tatsächlich gebraucht wird (und was das &quot;vollständige Objekt&quot; eigentlich ist.</p>
</blockquote>
<p>Ich hab's jetzt nicht ausprobiert, aber: Wenn ich ein Objekt mit dynamic_cast auf void* caste, gibt er mir dann nicht tatsächlich die Basisadresse des Objekts, wie Hume das behauptete?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1402596</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1402596</guid><dc:creator><![CDATA[Konrad Rudolph]]></dc:creator><pubDate>Tue, 13 Nov 2007 15:45:31 GMT</pubDate></item><item><title><![CDATA[Reply to derived* -&amp;gt; void* -&amp;gt; base* on Tue, 13 Nov 2007 15:47:52 GMT]]></title><description><![CDATA[<p>Bin ich mir nicht sicher - aber afaik liefert das die selbe Adresse wie der implizite Cast. Auf der anderen Seite kannst du nicht sicher sein, daß die Basisadresse des kompletten derived-Objektes mit der seines base-Anteils übereinstimmt (und der Compiler hat keine Möglichkeit, sich selber mitzuteilen, was hinter dem void* steht).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1402604</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1402604</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Tue, 13 Nov 2007 15:47:52 GMT</pubDate></item><item><title><![CDATA[Reply to derived* -&amp;gt; void* -&amp;gt; base* on Tue, 13 Nov 2007 15:56:41 GMT]]></title><description><![CDATA[<p>Uh, ich habe Humes Beitrag nicht aufmerksam genug gelesen. Ich dachte eigentlich an sowas hier:</p>
<pre><code class="language-cpp">void* pv = dynamic_cast&lt;Base*&gt;(pd);
</code></pre>
<p>Hier sollte IMHO durch den Cast die Typinfo hinzugezogen werden, sodass 'pv' tatsächlich die Basisadresse enthält. Dass man das ganze in einem untypisierten Zeiger speichert, sollte egal sein. Ob Humes Code standardkonform ist, bezweifle ich doch eher intuitiv.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1402609</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1402609</guid><dc:creator><![CDATA[Konrad Rudolph]]></dc:creator><pubDate>Tue, 13 Nov 2007 15:56:41 GMT</pubDate></item><item><title><![CDATA[Reply to derived* -&amp;gt; void* -&amp;gt; base* on Tue, 13 Nov 2007 16:18:31 GMT]]></title><description><![CDATA[<p>CStoll schrieb:</p>
<blockquote>
<p>Das gilt noch nicht einmal generell, das ist einfach nur Unsinn</p>
</blockquote>
<p>Recht hast du. Erst mal zu meinen Annahmen: ich ging, aufgrund des Beispiels, von einer eindeutigen Basisklasse aus und in diesem Fall ist es wichtig, dass man die Adresse des Basisklassenobjekts in den void-Pointer stopft (schließlich will man dahin auch wieder zurück). Mein Denkfehler lag nun darin, dass ich dachte: Adresse des vollständigen Objekts == Adresse des Basisklassenobjekts. Das gilt wohl aber nicht - der Standard garantiert, dass ein dynamic_cast&lt;void*&gt; mir ersteres liefert, dies ist aber nicht identisch zu letzterem. Letztlich geht es viel einfacher: man muss den Derived* schlicht über einen Base* nach void* casten.<br />
Sprich:</p>
<pre><code class="language-cpp">class Base {
public:
	virtual ~Base() {}
};

class Middle1 : public virtual Base {...};

class Middle2 : public virtual Base {...};

class Der : public Middle1, public Middle2 {...};

void f() {
   Middle2* p = new Der;
   void* q = static_cast&lt;Base*&gt;(p); // nicht q = p;
   // pass q to C-Api   
   // ...   
   Base* x = static_cast&lt;Base*&gt;(q);
   x-&gt;irgendWas():
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1402616</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1402616</guid><dc:creator><![CDATA[HumeSikkins]]></dc:creator><pubDate>Tue, 13 Nov 2007 16:18:31 GMT</pubDate></item><item><title><![CDATA[Reply to derived* -&amp;gt; void* -&amp;gt; base* on Tue, 13 Nov 2007 18:35:35 GMT]]></title><description><![CDATA[<p>das letzte stück code von humesikkins leuchtet mir ein. das problem ist, dass ich die casts nicht selber mache. das steckt alles in code aus einem code-generator (tolua++). den müsste ich dann wohl anpassen damit er tut was ich will.</p>
<pre><code class="language-cpp">class base
{
   void foo();
};

class derived : public base
{

};
</code></pre>
<p>wenn ich nun in lua ein derived habe und a_derived:foo() aufrufe, wird der funktionsaufruf im c++-teil immer auf ein base* ausgeführt, warum auch immer.</p>
<pre><code>-- in lua
bar = derived.new()
bar:foo()
</code></pre>
<p>wird zu</p>
<pre><code class="language-cpp">derived* tolua_ret = (derived*)  new derived();
tolua_pushusertype(tolua_S,(void*)tolua_ret,&quot;derived&quot;);
[...]
base* self = (base*)  tolua_tousertype(tolua_S,1,0);  // leider nicht derived*
self-&gt;foo();
</code></pre>
<p>böser fehler. syntaktisch korrekt, funktioniert aber nicht immer.<br />
ich kann das umgehen, indem ich foo() beim export nochmal explizit als memberfunction von derived angebe. ist nur mühselig.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1402711</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1402711</guid><dc:creator><![CDATA[luauser]]></dc:creator><pubDate>Tue, 13 Nov 2007 18:35:35 GMT</pubDate></item><item><title><![CDATA[Reply to derived* -&amp;gt; void* -&amp;gt; base* on Wed, 14 Nov 2007 06:56:07 GMT]]></title><description><![CDATA[<p>foo() ist ja auch eine Methode der Basisklasse - woher soll Lua da wissen, daß es kein Basis-Objekt hat? (vielleicht reicht es ja schon, wenn du die Methode virtuell machst)</p>
<p>PS: Das Problem scheint weniger auf der C++ Seite, sondern auf der Lua-Seite zu liegen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1402858</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1402858</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Wed, 14 Nov 2007 06:56:07 GMT</pubDate></item><item><title><![CDATA[Reply to derived* -&amp;gt; void* -&amp;gt; base* on Wed, 14 Nov 2007 08:21:04 GMT]]></title><description><![CDATA[<p>CStoll schrieb:</p>
<blockquote>
<p>foo() ist ja auch eine Methode der Basisklasse - woher soll Lua da wissen, daß es kein Basis-Objekt hat?</p>
</blockquote>
<p>genau genommen weiß lua überhaupt nichts über das objekt. für lua ist es nur eine tabelle mit ein paar werten. aber der code-generator weiß es, wenn er die bindings generiert.</p>
<p>CStoll schrieb:</p>
<blockquote>
<p>(vielleicht reicht es ja schon, wenn du die Methode virtuell machst)</p>
</blockquote>
<p>macht keinen unterschied.</p>
<blockquote>
<p>PS: Das Problem scheint weniger auf der C++ Seite, sondern auf der Lua-Seite zu liegen.</p>
</blockquote>
<p>wie schon gesagt, es liegt am code-generator der die bindings generiert. der generiert standardmäßig keine funktion für derived::foo(), weil er meint einfach nach base* casten und dessen foo() aufrufen zu können.<br />
ich kann ihm einfach eine klassendefinition unterschieben, die derived::foo() nochmal explizit angibt (auch wenn sie eigentlich nicht existiert), dann castet er richtig. ist aber wie gesagt sehr mühselig. und wenig intuitiv.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1402889</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1402889</guid><dc:creator><![CDATA[luauser]]></dc:creator><pubDate>Wed, 14 Nov 2007 08:21:04 GMT</pubDate></item><item><title><![CDATA[Reply to derived* -&amp;gt; void* -&amp;gt; base* on Wed, 14 Nov 2007 08:27:54 GMT]]></title><description><![CDATA[<p>Wie gesagt: Das ist kein Problem von C++ (das hat eine &quot;klare&quot; Semanti für diesen Fall - &quot;undefined behaviour&quot;), sondern von Lua bzw. vom Code-Generator. Und anscheinend verwendet der die statischen Typ-Informationen zur Code-Erzeugung - foo() ist eine Methode der Basisklasse, also holt er sich auch ein Basis-Objekt.</p>
<p>PS: Nein, ich kenne mich nicht mit Lua aus - das sind nur Vermutungen anhand der Fragmente, die du geliefert hast. Aber ich geb dir gerne einen Gratis-Schubs ins richtige Board.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1402896</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1402896</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Wed, 14 Nov 2007 08:27:54 GMT</pubDate></item><item><title><![CDATA[Reply to derived* -&amp;gt; void* -&amp;gt; base* on Wed, 14 Nov 2007 08:28:04 GMT]]></title><description><![CDATA[<p>Dieser Thread wurde von Moderator/in <a href="http://www.c-plusplus.net/forum/profile-var-mode-is-viewprofile-and-u-is-18038.html" rel="nofollow">CStoll</a> aus dem Forum <a href="http://www.c-plusplus.net/forum/viewforum-var-f-is-15.html" rel="nofollow">C++</a> in das Forum <a href="http://www.c-plusplus.net/forum/viewforum-var-f-is-8.html" rel="nofollow">Rund um die Programmierung</a> verschoben.</p>
<p>Im Zweifelsfall bitte auch folgende Hinweise beachten:<br />
<a href="http://www.c-plusplus.net/forum/viewtopic-var-t-is-39405.html" rel="nofollow">C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?</a></p>
<p><em>Dieses Posting wurde automatisch erzeugt.</em></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1402897</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1402897</guid><dc:creator><![CDATA[C++ Forumbot]]></dc:creator><pubDate>Wed, 14 Nov 2007 08:28:04 GMT</pubDate></item></channel></rss>