<?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[Polymorphes Objekt in &amp;quot;untypisiertem&amp;quot; Speicherbereich]]></title><description><![CDATA[<p>Hallo da.<br />
Folgende Situation: Ich bekomme von einer API einen Speichbereich in &quot;beliebiger&quot; Größe, den ich eigentlich nutzen kann wie ich will. Was ich darin nun ablegen &quot;muss&quot;, ist ein polymorphes Objekt. Sodass ich, wenn ich an anderer Stelle wieder einen Zeiger auf diesen Speicherbereich bekomme, irgendwie einen Zeiger auf die gemeinsame Basisklasse erhalte.<br />
Nun kann man ja nicht erwarten, dass wenn ich per placement-new eine Instanz einer konreten Instanz am Anfang des Puffers erzeuge, unbedingt die gewollte Basisklasse am &quot;Anfang&quot; des Puffers landet, ich also reinterpret_cast&lt;Basisklasse*&gt;(puffer_ptr) sicher machen kann. Aber ich möchte nun auch nicht unbedingt am Anfang des Bereichs einen Zeiger auf die Basisklasse ablegen müssen. Andererseits weiß ich aber genau, welche Klassen darin landen können, und ich habe Kontrolle über alle. Wenn sie also alle nur einfache Ableitungen haben, kann man mit einiger Sicherheit sagen, dass der Cast dennoch so ziemlich überall klappen würde?</p>
<p>Viele Grüße</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/333743/polymorphes-objekt-in-quot-untypisiertem-quot-speicherbereich</link><generator>RSS for Node</generator><lastBuildDate>Sun, 26 Apr 2026 11:37:52 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/333743.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 28 Jul 2015 23:20:04 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Polymorphes Objekt in &amp;quot;untypisiertem&amp;quot; Speicherbereich on Tue, 28 Jul 2015 23:20:04 GMT]]></title><description><![CDATA[<p>Hallo da.<br />
Folgende Situation: Ich bekomme von einer API einen Speichbereich in &quot;beliebiger&quot; Größe, den ich eigentlich nutzen kann wie ich will. Was ich darin nun ablegen &quot;muss&quot;, ist ein polymorphes Objekt. Sodass ich, wenn ich an anderer Stelle wieder einen Zeiger auf diesen Speicherbereich bekomme, irgendwie einen Zeiger auf die gemeinsame Basisklasse erhalte.<br />
Nun kann man ja nicht erwarten, dass wenn ich per placement-new eine Instanz einer konreten Instanz am Anfang des Puffers erzeuge, unbedingt die gewollte Basisklasse am &quot;Anfang&quot; des Puffers landet, ich also reinterpret_cast&lt;Basisklasse*&gt;(puffer_ptr) sicher machen kann. Aber ich möchte nun auch nicht unbedingt am Anfang des Bereichs einen Zeiger auf die Basisklasse ablegen müssen. Andererseits weiß ich aber genau, welche Klassen darin landen können, und ich habe Kontrolle über alle. Wenn sie also alle nur einfache Ableitungen haben, kann man mit einiger Sicherheit sagen, dass der Cast dennoch so ziemlich überall klappen würde?</p>
<p>Viele Grüße</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2461383</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2461383</guid><dc:creator><![CDATA[decimad]]></dc:creator><pubDate>Tue, 28 Jul 2015 23:20:04 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorphes Objekt in &amp;quot;untypisiertem&amp;quot; Speicherbereich on Tue, 28 Jul 2015 23:43:05 GMT]]></title><description><![CDATA[<p>decimad schrieb:</p>
<blockquote>
<p>.<br />
Nun kann man ja nicht erwarten, dass wenn ich per placement-new eine Instanz einer konreten Instanz am Anfang des Puffers erzeuge, unbedingt die gewollte Basisklasse am &quot;Anfang&quot; des Puffers landet</p>
</blockquote>
<p>Doch, kannst du! Die Basisklassen liegen am Anfang des Objekts. Im Falle von Mehrfachvererbung eine nach der anderen.</p>
<blockquote>
<p>, ich also reinterpret_cast&lt;Basisklasse*&gt;(puffer_ptr) sicher machen kann.</p>
</blockquote>
<p>Und wenn du einen static_cast benutzt, dann würde das sogar automatisch sicher klappen. Siehe und staune:</p>
<pre><code>#include &lt;iostream&gt;

struct Base1 { int a; };
struct Base2 { int b; };

struct Derived : public Base1, public Base2
{
  void print_address()
  {
    std::cout &lt;&lt; &quot;Myself: &quot; &lt;&lt; this &lt;&lt; '\n'
              &lt;&lt; &quot;My Base1: &quot; &lt;&lt; &amp;a &lt;&lt; '\n'
              &lt;&lt; &quot;My Base2: &quot; &lt;&lt; &amp;b &lt;&lt; '\n';
  }
};

int main()
{
  Derived d;
  d.print_address();
  Derived *p = &amp;d;
  std::cout &lt;&lt; &quot;Derived pointer: &quot; &lt;&lt; p &lt;&lt; '\n'
            &lt;&lt; &quot;Base1 pointer: &quot; &lt;&lt; static_cast&lt;Base1*&gt;(p) &lt;&lt; '\n'
            &lt;&lt; &quot;Base2 pointer: &quot; &lt;&lt; static_cast&lt;Base2*&gt;(p) &lt;&lt; '\n';  
}
</code></pre>
<p>(Irgendwie funktioniert <a href="http://ideone.com" rel="nofollow">ideone.com</a> bei mir gerade nicht richtig <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /> . Muss also selber übersetzt werden.) Mögliche Beispielausgabe:</p>
<pre><code>Myself: 0x7ffdc47ba240
My Base1: 0x7ffdc47ba240
My Base2: 0x7ffdc47ba244
Derived pointer: 0x7ffdc47ba240
Base1 pointer: 0x7ffdc47ba240
Base2 pointer: 0x7ffdc47ba244
</code></pre>
<p>Wenn du untypisierten Speicher hast, musst du natürlich erst einmal irgendwie wissen, was das für ein Objekt ist, bevor du dann über die entsprechenden Casts die Adressen der Basisklassen erhalten kannst. Aber wahrscheinlich stellen sich diese Fragen gar nicht, denn so lange du keine Mehrfachvererbung hast, ist wie gesagt garantiert, dass die Basisobjektadresse mit der Objektadresse identisch ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2461384</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2461384</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Tue, 28 Jul 2015 23:43:05 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorphes Objekt in &amp;quot;untypisiertem&amp;quot; Speicherbereich on Tue, 28 Jul 2015 23:56:16 GMT]]></title><description><![CDATA[<p>Oh cool, normalerweise ist doch in C++ immer alles undefiniertes verhalten, was einfach an sich praktisch wäre!<br />
Also wenn ich eine einfache Vererbungshierarchie habe, ist das gantiert, ansonsten kommt es auf die Reiheinfolge der Basisklassen in &quot;Breadth-First&quot; sozusagen an?<br />
Danke für die Info, das stimmt mich glücklich!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2461385</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2461385</guid><dc:creator><![CDATA[decimad]]></dc:creator><pubDate>Tue, 28 Jul 2015 23:56:16 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorphes Objekt in &amp;quot;untypisiertem&amp;quot; Speicherbereich on Tue, 28 Jul 2015 23:57:38 GMT]]></title><description><![CDATA[<p>Ich finde die Idee einen Zeiger (oder Offset) in den ersten Bytes abzuspeichern gar nicht so dumm.</p>
<ol>
<li>Zeiger auf den Block-Anfang holen, Platz für den Offset draufaddieren</li>
<li><code>std::align</code> aufrufen um für passendes Alignment für das zu erstellende Objekt zu sorgen</li>
<li>Mit dem nun passend alignten Zeiger placement new aufrufen</li>
<li>Zeiger zur gewünschte Basisklasse casten</li>
<li>Basisklassenzeiger mit <code>memcpy</code> an den Anfang des Blocks kopieren</li>
</ol>
]]></description><link>https://www.c-plusplus.net/forum/post/2461386</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2461386</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 28 Jul 2015 23:57:38 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorphes Objekt in &amp;quot;untypisiertem&amp;quot; Speicherbereich on Wed, 29 Jul 2015 00:04:13 GMT]]></title><description><![CDATA[<p>SeppJ schrieb:</p>
<blockquote>
<p>decimad schrieb:</p>
<blockquote>
<p>.<br />
Nun kann man ja nicht erwarten, dass wenn ich per placement-new eine Instanz einer konreten Instanz am Anfang des Puffers erzeuge, unbedingt die gewollte Basisklasse am &quot;Anfang&quot; des Puffers landet</p>
</blockquote>
<p>Doch, kannst du! Die Basisklassen liegen am Anfang des Objekts. Im Falle von Mehrfachvererbung eine nach der anderen.</p>
</blockquote>
<p>C++11 schrieb:</p>
<blockquote>
<p>[class.derived]/4 The order in which the base class subobjects are allocated in the most derived object (1.8) is unspecified.</p>
</blockquote>
<p>Aber immerhin hast du eine schöne empirische Bestätigung geliefert. In der Itanium ABI ist es nämlich garantiert</p>
<p><a href="https://mentorembedded.github.io/cxx-abi/abi.html" rel="nofollow">https://mentorembedded.github.io/cxx-abi/abi.html</a> schrieb:</p>
<blockquote>
<p>For each data component D (first the primary base of C, if any, then the non-primary, non-virtual direct base classes in declaration order, then the non-static data members and unnamed bitfields in declaration order), allocate as follows:</p>
</blockquote>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/13960">@hustbaer</a>: Das sollte funktionieren.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2461387</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2461387</guid><dc:creator><![CDATA[citation needed]]></dc:creator><pubDate>Wed, 29 Jul 2015 00:04:13 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorphes Objekt in &amp;quot;untypisiertem&amp;quot; Speicherbereich on Wed, 29 Jul 2015 00:06:43 GMT]]></title><description><![CDATA[<p>decimad schrieb:</p>
<blockquote>
<p>Also wenn ich eine einfache Vererbungshierarchie habe, ist das gantiert, ansonsten kommt es auf die Reiheinfolge der Basisklassen in &quot;Breadth-First&quot; sozusagen an?</p>
</blockquote>
<p>Wie kommst du jetzt auf Breadth-First? Das von SeppJ beschriebene Verfahren ist Depth-first.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2461388</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2461388</guid><dc:creator><![CDATA[citation needed]]></dc:creator><pubDate>Wed, 29 Jul 2015 00:06:43 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorphes Objekt in &amp;quot;untypisiertem&amp;quot; Speicherbereich on Wed, 29 Jul 2015 00:11:08 GMT]]></title><description><![CDATA[<p>decimad schrieb:</p>
<blockquote>
<p>Also wenn ich eine einfache Vererbungshierarchie habe, ist das gantiert, ansonsten kommt es auf die Reiheinfolge der Basisklassen in &quot;Breadth-First&quot; sozusagen an?</p>
</blockquote>
<p>Ich muss es leider korrigieren: Es ist doch nicht garantiert, dass dieses genaue Layout vorliegt. Das heißt, die richtige Nutzung ist hier über static_cast oder dynamic_cast, die, wie von mir gezeigt, das Layout kennen und die Zeiger auf die richtige Weise verbiegen können. Implizite Casts funktionieren natürlich auch:</p>
<pre><code>Derived *p = &amp;d;
  Base1 *b1 = p;
  Base2 *b2 = p;

  std::cout &lt;&lt; &quot;Derived pointer: &quot; &lt;&lt; p &lt;&lt; '\n'
            &lt;&lt; &quot;Base1 pointer: &quot; &lt;&lt; b1 &lt;&lt; '\n'
            &lt;&lt; &quot;Base2 pointer: &quot; &lt;&lt; b2 &lt;&lt; '\n';
</code></pre>
<p>Liefert das gleiche Ergebnis wie mein vorheriges Beispiel.</p>
<p>citation needed schrieb:</p>
<blockquote>
<p>Aber immerhin hast du eine schöne empirische Bestätigung geliefert. In der Itanium ABI ist es nämlich garantiert</p>
<p><a href="https://mentorembedded.github.io/cxx-abi/abi.html" rel="nofollow">https://mentorembedded.github.io/cxx-abi/abi.html</a> schrieb:</p>
<blockquote>
<p>For each data component D (first the primary base of C, if any, then the non-primary, non-virtual direct base classes in declaration order, then the non-static data members and unnamed bitfields in declaration order), allocate as follows:</p>
</blockquote>
</blockquote>
<p>Ahh, daher hatte ich das also. Ich war mir nämlich sicher, dass das irgendwo garantiert war, bevor ich dann selbstständig auf die von dir zitierte Stelle im C++-Standard stieß.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2461389</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2461389</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Wed, 29 Jul 2015 00:11:08 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorphes Objekt in &amp;quot;untypisiertem&amp;quot; Speicherbereich on Wed, 29 Jul 2015 00:16:36 GMT]]></title><description><![CDATA[<p>Stimmt, was SeppJ geschrieben hat, bedeutet nach etwas Überlegung für mich wirklich Depth-First (zumindest wenn man sich denkt, dass eine Klasse &quot;zusammenhängend&quot; mit ihren Basisklassen enthalten ist). Wenn ich es nicht erwähnt hätte, wäre es mir jetzt uach nicht klar geworden <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>
<p>Dass es doch nicht garantiert wird, ist wiederum ärgerlich. Jetzt kann ich wirklich den Zeigeransatz verfolgen, oder vielleicht besser komplett auf irgendeinen Polymorpheie-C++-Klassen-Firlefanz an der Stelle verzichten.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2461390</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2461390</guid><dc:creator><![CDATA[decimad]]></dc:creator><pubDate>Wed, 29 Jul 2015 00:16:36 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorphes Objekt in &amp;quot;untypisiertem&amp;quot; Speicherbereich on Wed, 29 Jul 2015 00:47:41 GMT]]></title><description><![CDATA[<p>decimad schrieb:</p>
<blockquote>
<p>Dass es doch nicht garantiert wird, ist wiederum ärgerlich.</p>
</blockquote>
<p>Wieso? Du weißt doch anscheinend, was für ein Objekt das ist. Und wenn du das weißt, dann weiß der Compiler für dich die korrekten relativen Adressen der Basisobjekte. Bloß die Funktion eines reinterpret_cast ist nicht garantiert. So wie eigentlich immer, wenn reinterpret_cast im Spiel ist <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>
]]></description><link>https://www.c-plusplus.net/forum/post/2461393</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2461393</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Wed, 29 Jul 2015 00:47:41 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorphes Objekt in &amp;quot;untypisiertem&amp;quot; Speicherbereich on Wed, 29 Jul 2015 00:51:20 GMT]]></title><description><![CDATA[<p>Nein, ich weiß ja nicht, was für ein Objekt es ist, ich richte es nur so ein, das was auch immer da drin steckt, von einer bestimmten Klasse ableitet... das ist ja das zu lösende Problem. Wenn ich also von dem Speicherbereichzeiger nicht auf einen Basisklassen-Zeiger schließen kann, kann ich genauso gut ein Enum an den Anfang packen und mir die Basisklasse sparen, sondern direkt zu konkreten Klassen casten, basierend auf dem Enum.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2461394</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2461394</guid><dc:creator><![CDATA[decimad]]></dc:creator><pubDate>Wed, 29 Jul 2015 00:51:20 GMT</pubDate></item></channel></rss>