<?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 Speichern]]></title><description><![CDATA[<p>Hallo,<br />
angenommen ich habe folgende Klassen:</p>
<pre><code class="language-cpp">struct Human
{int x;};

struct Male : public Human
{unsigned char y;};

struct Female : public Human
{long double z;};

struct Container
{
	shared_ptr&lt;Base&gt; ptr;
};
</code></pre>
<p>und möchte den Output-Operator überladen, um Cointainer-Objekte in einer Datei zu speichern, wie löse ich dies am besten? Der Pointer ptr kann ja auf ein Human-, ein Male- oder ein Female-Objekt zeigen, die alle verschiedene Größen haben.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/301042/polymorphes-speichern</link><generator>RSS for Node</generator><lastBuildDate>Wed, 12 Aug 2026 06:37:47 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/301042.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 17 Mar 2012 18:58:05 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Polymorphes Speichern on Sat, 17 Mar 2012 18:58:05 GMT]]></title><description><![CDATA[<p>Hallo,<br />
angenommen ich habe folgende Klassen:</p>
<pre><code class="language-cpp">struct Human
{int x;};

struct Male : public Human
{unsigned char y;};

struct Female : public Human
{long double z;};

struct Container
{
	shared_ptr&lt;Base&gt; ptr;
};
</code></pre>
<p>und möchte den Output-Operator überladen, um Cointainer-Objekte in einer Datei zu speichern, wie löse ich dies am besten? Der Pointer ptr kann ja auf ein Human-, ein Male- oder ein Female-Objekt zeigen, die alle verschiedene Größen haben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2192448</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2192448</guid><dc:creator><![CDATA[Wurstinator]]></dc:creator><pubDate>Sat, 17 Mar 2012 18:58:05 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorphes Speichern on Sat, 17 Mar 2012 19:03:05 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">struct Human 
{
  virtual ostream&amp; WriteTo(ostream&amp; os) const{ return os &lt;&lt; x; }
  int x;
}; 

struct Male : public Human 
{
   ostream&amp; WriteTo(ostream&amp; os) const override { Human::WriteTo(os); return os &lt;&lt; y; }
   unsigned char y;
}; 

//und so weiter...

ostream&amp; operator&lt;&lt;(ostream&amp; os, const Human&amp; human)
{
   return human.WriteTo(os);
}

int main()
{
  Container container;
  container.ptr = new Male();
  cout &lt;&lt; *container.ptr &lt;&lt; endl;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2192450</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2192450</guid><dc:creator><![CDATA[*Q* 1]]></dc:creator><pubDate>Sat, 17 Mar 2012 19:03:05 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorphes Speichern on Sat, 17 Mar 2012 21:04:50 GMT]]></title><description><![CDATA[<p>Okay, danke.</p>
<p>Was ich vergessen habe zu fragen: Wie sieht es mit dem Laden aus? Ich habe also einen ifstream und möchte aus diesem wieder den ursprünglichen Container wiederherstellen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2192458</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2192458</guid><dc:creator><![CDATA[Wurstinator]]></dc:creator><pubDate>Sat, 17 Mar 2012 21:04:50 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorphes Speichern on Sat, 17 Mar 2012 21:12:42 GMT]]></title><description><![CDATA[<p>Auch wenn ich polymorphes Laden etwas komisch finde: Jetzt, wo du die Lösung fürs Speichern siehst, kommst du da nicht auf eine Möglichkeit zum Laden?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2192461</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2192461</guid><dc:creator><![CDATA[cooky451]]></dc:creator><pubDate>Sat, 17 Mar 2012 21:12:42 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorphes Speichern on Sun, 18 Mar 2012 11:40:52 GMT]]></title><description><![CDATA[<p>Das einlesen von objekten ist bei c++ so eine sache...</p>
<p>Ich kenn da jetzt nur manuelle umständliche Lösungen, ungefähr so:</p>
<pre><code class="language-cpp">class Human
{
public:
   enum HumanType
   {
       Male, Female
   };
   Human(){x = 0;}
   Human(istream&amp; is){is &gt;&gt; x; }
   virtual ostream&amp; WriteTo(ostream&amp; os) const {return os &lt;&lt; GetType() &lt;&lt; x;} 
protected:
   virtual HumanType GetType() const = 0;
private:
   int x;
};

class Male : public Human
{
public:
   Male(){y = 0;}
   Male(istream&amp; is) : Human(is) {is &gt;&gt; y;}
   ostream&amp; WriteTo(ostream&amp; os) const override { Human::WriteTo(os); return os &lt;&lt; y;}
protected:
   virtual Human::HumanType GetType() const override {return Human::Male;}
private:
   int y;
};

//Female analog

//wenn du willst, kannst du auch einen smart_ptr oder deine container-klasse zurückgeben
Human * LoadHuman(istream&amp; is)
{
   Human::HumanType type;
   is &gt;&gt; type;
   switch(type)
   {
     case Human::Male:
        return new Male(is);
     case Human:Female:
        return new Female(is);
     default:
        throw sthg;
   }
}
</code></pre>
<p>Das ganze ist viel Aufwand und nicht unbedingt schön. Aber für C++ kenn ich keine anderen Lösungen, die ohne Codegeneratoren funktionieren.</p>
<p>Edit: vielleicht hilft dir boost::serialization. Ich bin mir aber nicht sicher, ob das sowas kann.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2192503</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2192503</guid><dc:creator><![CDATA[*Q* 1]]></dc:creator><pubDate>Sun, 18 Mar 2012 11:40:52 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorphes Speichern on Sun, 18 Mar 2012 20:40:22 GMT]]></title><description><![CDATA[<p>Q schrieb:</p>
<blockquote>
<pre><code class="language-cpp">class Human
{
public:
   enum HumanType
   {
       Male, Female
   };
};

Human * LoadHuman(istream&amp; is)
{
   Human::HumanType type;
   is &gt;&gt; type;
   switch(type)
   {
     case Human::Male:
        return new Male(is);
     case Human:Female:
        return new Female(is);
     default:
        throw sthg;
   }
}
</code></pre>
</blockquote>
<p>Ich würde übrigends empfehlen, bei größeren Mengen an möglichen Klassen statt einem switch ein Array von Human* (*)(std::istream&amp;) zu verwenden, da kann man entsprechend statt einem switch einfach return Tabelle[type](is); schreiben. Prüfen, ob der Wert gültig ist, müsste man trotzdem noch über ein if, vielleicht mit Hilfe eines Maximalwerts im enum, a lá Human::max.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2192636</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2192636</guid><dc:creator><![CDATA[Cachus]]></dc:creator><pubDate>Sun, 18 Mar 2012 20:40:22 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorphes Speichern on Sun, 18 Mar 2012 22:28:21 GMT]]></title><description><![CDATA[<p>@ cooky451: Einfach eine virtuelle Funktion machen geht ja nicht, da das Programm ja nicht wissen kann, welcher Typ gerade gelesen wird.</p>
<p>@ Q:</p>
<blockquote>
<p>As can be seen in demo.cpp, serialization of pointers to derived classes through a base clas pointer may require explicit enumeration of the derived classes to be serialized.</p>
</blockquote>
<p>Die Library bietet dafür wohl ein System an. Es scheint einfacher zu sein, als das Enum-Zeug, aber leider auch nicht so einfach, wie ich es mir gewünscht hätte.<br />
Naja, muss ich wohl mit leben, danke für den Hinweis auf boost.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2192651</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2192651</guid><dc:creator><![CDATA[Wurstinator]]></dc:creator><pubDate>Sun, 18 Mar 2012 22:28:21 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorphes Speichern on Sun, 18 Mar 2012 22:56:40 GMT]]></title><description><![CDATA[<p>Wurstinator schrieb:</p>
<blockquote>
<p>@ cooky451: Einfach eine virtuelle Funktion machen geht ja nicht, da das Programm ja nicht wissen kann, welcher Typ gerade gelesen wird.</p>
</blockquote>
<p>Doch, schon. Ich weiß was du meinst, aber das ist eine völlig andere Frage. Das hat nichts mehr mit Polymorphie zu tun. Du musst dir halt ein Format überlegeben, bei dem du beim Einlesen die verschiedenen Typen unterscheiden kannst.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2192662</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2192662</guid><dc:creator><![CDATA[cooky451]]></dc:creator><pubDate>Sun, 18 Mar 2012 22:56:40 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorphes Speichern on Tue, 20 Mar 2012 10:13:51 GMT]]></title><description><![CDATA[<p>Wurstinator schrieb:</p>
<blockquote>
<p>Einfach eine virtuelle Funktion machen geht ja nicht, da das Programm ja nicht wissen kann, welcher Typ gerade gelesen wird.</p>
</blockquote>
<p>Jein. Google mal nach &quot;virtual constructor&quot; und &quot;factory method&quot;</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2193150</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2193150</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Tue, 20 Mar 2012 10:13:51 GMT</pubDate></item></channel></rss>