<?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[Speicherlayout von Kindklassen]]></title><description><![CDATA[<p>Wenn ich eine Klasse mit zwei Kindklassen habe die der Basisklasse keine Datenmember hinzufügen:</p>
<pre><code class="language-cpp">class Base{
 int element1;
 double element2;
};

class Foo: public Base{};
class Bar: public Base{};
</code></pre>
<p>Kann ich dann garantiert davon ausgehen, dass Foo, Bar und Base das gleiche Speicherlayout haben? Mit gleichem Speicherlayout meine ich, dass (&amp;element2 - &amp;element1) bei allen dreien das selbe ergibt.</p>
<p>Zweck der ganzen Geschichte: Foo und Bar fügen Base ein paar statische Methoden hinzu, daher dieses Design. Nun will ich Objekte dieser Klassen mittels MPI senden/empfangen und dafür muss man das Speicherlayout kennen. Es würde Arbeit sparen, wenn das Programm das Layout nur einmal an Base ausmisst und es dann für die abgeleiteten Klassen verwenden kann.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/253515/speicherlayout-von-kindklassen</link><generator>RSS for Node</generator><lastBuildDate>Sun, 13 Sep 2026 16:49:07 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/253515.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 03 Nov 2009 14:34:39 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Speicherlayout von Kindklassen on Tue, 03 Nov 2009 14:34:39 GMT]]></title><description><![CDATA[<p>Wenn ich eine Klasse mit zwei Kindklassen habe die der Basisklasse keine Datenmember hinzufügen:</p>
<pre><code class="language-cpp">class Base{
 int element1;
 double element2;
};

class Foo: public Base{};
class Bar: public Base{};
</code></pre>
<p>Kann ich dann garantiert davon ausgehen, dass Foo, Bar und Base das gleiche Speicherlayout haben? Mit gleichem Speicherlayout meine ich, dass (&amp;element2 - &amp;element1) bei allen dreien das selbe ergibt.</p>
<p>Zweck der ganzen Geschichte: Foo und Bar fügen Base ein paar statische Methoden hinzu, daher dieses Design. Nun will ich Objekte dieser Klassen mittels MPI senden/empfangen und dafür muss man das Speicherlayout kennen. Es würde Arbeit sparen, wenn das Programm das Layout nur einmal an Base ausmisst und es dann für die abgeleiteten Klassen verwenden kann.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1802692</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1802692</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Tue, 03 Nov 2009 14:34:39 GMT</pubDate></item><item><title><![CDATA[Reply to Speicherlayout von Kindklassen on Tue, 03 Nov 2009 15:27:00 GMT]]></title><description><![CDATA[<p>SeppJ schrieb:</p>
<blockquote>
<pre><code class="language-cpp">class Base{
 int element1;
 double element2;
};

class Foo: public Base{};
class Bar: public Base{};
</code></pre>
<p>Kann ich dann garantiert davon ausgehen, dass Foo, Bar und Base das gleiche Speicherlayout haben?</p>
</blockquote>
<p>Nein.</p>
<p>SeppJ schrieb:</p>
<blockquote>
<p>Mit gleichem Speicherlayout meine ich, dass (&amp;element2 - &amp;element1) bei allen dreien das selbe ergibt.</p>
</blockquote>
<p>Kannst Du die Bedingung anders formulieren? &amp;element2-&amp;element1 ist Quatsch -- selbst wenn element1 und element2 vom gleichen Typen wären.</p>
<p>SeppJ schrieb:</p>
<blockquote>
<p>Zweck der ganzen Geschichte: Foo und Bar fügen Base ein paar statische Methoden hinzu, daher dieses Design.</p>
</blockquote>
<p>Was bringt das? Gibt's in dem &quot;echten&quot; Base geschützte Elemente (protected) auf denen Du so zugreifen kannst?</p>
<p>SeppJ schrieb:</p>
<blockquote>
<p>Nun will ich Objekte dieser Klassen mittels MPI senden/empfangen und dafür muss man das Speicherlayout kennen.</p>
</blockquote>
<p>Jein. Geht das noch konkreter? Also Base ist ein POD. Solange es keine Zeiger enthält und alle Rechner die gleiche OS/Compiler-Kombination mit denselben Optionen benutzen, kannst Du ein Foo* in ein Base* und dann in ein void* verwandeln und anschließend die ersten sizeof(Base) Bytes auf den Weg schicken. Die Frage ist, was soll dann auf der Empfängerseite passieren?</p>
<p>Gruß,<br />
SP</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1802735</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1802735</guid><dc:creator><![CDATA[Sebastian Pizer]]></dc:creator><pubDate>Tue, 03 Nov 2009 15:27:00 GMT</pubDate></item><item><title><![CDATA[Reply to Speicherlayout von Kindklassen on Tue, 03 Nov 2009 16:03:53 GMT]]></title><description><![CDATA[<p>Sebastian Pizer schrieb:</p>
<blockquote>
<p>SeppJ schrieb:</p>
<blockquote>
<p>Kann ich dann garantiert davon ausgehen, dass Foo, Bar und Base das gleiche Speicherlayout haben?</p>
</blockquote>
<p>Nein.</p>
</blockquote>
<p>Ok, das ist schonmal ungünstig, dann muss ich wohl sowieso das Layout für jede Klasse neu ausrechnen.</p>
<blockquote>
<p>SeppJ schrieb:</p>
<blockquote>
<p>Mit gleichem Speicherlayout meine ich, dass (&amp;element2 - &amp;element1) bei allen dreien das selbe ergibt.</p>
</blockquote>
<p>Kannst Du die Bedingung anders formulieren? &amp;element2-&amp;element1 ist Quatsch -- selbst wenn element1 und element2 vom gleichen Typen wären.</p>
</blockquote>
<p>Etwas ungünstig formuliert, ich wollte nicht zuviel MPI reinbringen, aber das ist wohl doch nötig: MPI hat eine Funktion MPI_GetAddress, die eine Adresse in einem bestimmten MPI internen Adressformat liefert (vermutlich einfach ein Typedef auf int). Damit kann man bei zusammengesetzten Typen berechnen, welchen Abstand die Datenelemente im Speicher haben. Damit kann man dann neue, versendbare Datentypen konstruieren, die intern diese Abstände verwenden.</p>
<blockquote>
<p>SeppJ schrieb:</p>
<blockquote>
<p>Zweck der ganzen Geschichte: Foo und Bar fügen Base ein paar statische Methoden hinzu, daher dieses Design.</p>
</blockquote>
<p>Was bringt das? Gibt's in dem &quot;echten&quot; Base geschützte Elemente (protected) auf denen Du so zugreifen kannst?</p>
</blockquote>
<p>Genauso ist es.</p>
<blockquote>
<p>SeppJ schrieb:</p>
<blockquote>
<p>Nun will ich Objekte dieser Klassen mittels MPI senden/empfangen und dafür muss man das Speicherlayout kennen.</p>
</blockquote>
<p>Jein. Geht das noch konkreter? Also Base ist ein POD. Solange es keine Zeiger enthält und alle Rechner die gleiche OS/Compiler-Kombination mit denselben Optionen benutzen, kannst Du ein Foo* in ein Base* und dann in ein void* verwandeln und anschließend die ersten sizeof(Base) Bytes auf den Weg schicken. Die Frage ist, was soll dann auf der Empfängerseite passieren?</p>
</blockquote>
<p>Also es ist naturgemäß bei allen Prozessen der gleiche Binärcode, und exakt gleiche Systeme. Und es wird auch nur POD versendet, MPI und Deepcopy passt glaube ich nicht so gut zusammen, zumindest nicht ohne Tricksereien.</p>
<p>Das was du da beschreibst, bedeutet aber doch, dass Foo und Base für die Datenelemente das gleiche Layout haben. Ich vermute mal, dass MPI intern ziemlich ähnlich arbeitet, man übergibt einen Zeiger auf das zu versendende Objekt, dieses wird intern umgecastet und dann versendet.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1802765</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1802765</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Tue, 03 Nov 2009 16:03:53 GMT</pubDate></item><item><title><![CDATA[Reply to Speicherlayout von Kindklassen on Tue, 03 Nov 2009 16:29:26 GMT]]></title><description><![CDATA[<p>Bei sowas serialisiert man besser. Gib der Basisklasse ein serialize() und unserialize() und gut ist.<br />
Ist kein nennenswerter Mehraufwand und Probleme sind ausgeschlossen, da man sich nicht ins Reich der undefined behaviour begibt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1802777</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1802777</guid><dc:creator><![CDATA[Nanyuki]]></dc:creator><pubDate>Tue, 03 Nov 2009 16:29:26 GMT</pubDate></item><item><title><![CDATA[Reply to Speicherlayout von Kindklassen on Tue, 03 Nov 2009 19:28:38 GMT]]></title><description><![CDATA[<p>SeppJ schrieb:</p>
<blockquote>
<p>Sebastian Pizer schrieb:</p>
<blockquote>
<p>Also Base ist ein POD. Solange es keine Zeiger enthält und alle Rechner die gleiche OS/Compiler-Kombination mit denselben Optionen benutzen, kannst Du ein Foo* in ein Base* und dann in ein void* verwandeln und anschließend die ersten sizeof(Base) Bytes auf den Weg schicken. Die Frage ist, was soll dann auf der Empfängerseite passieren?</p>
</blockquote>
<p>[...]<br />
Das was du da beschreibst, bedeutet aber doch, dass Foo und Base für die Datenelemente das gleiche Layout haben.</p>
</blockquote>
<p>Das bedeutet, dass in dem Foo-Objekt ein Base-Objekt drinsteht. Das bedeutet aber nicht, dass sizeof(Foo)==sizeof(Base) garantiert wird, oder dass Foo*-&gt;Base*-&gt;void* dieselbe Adresse liefert wie Foo*-&gt;void*. Die relative Anordnung der Bits und Bytes des Base-Objekts ist immer die gleiche, da POD. Bei nicht-PODs gibt es diese Garantie nicht mehr.</p>
<p>Gruß,<br />
SP</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1802857</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1802857</guid><dc:creator><![CDATA[Sebastian Pizer]]></dc:creator><pubDate>Tue, 03 Nov 2009 19:28:38 GMT</pubDate></item></channel></rss>