<?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[vector mit unterschiedlichen Typen?]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>ich wollte mal wissen, ob es generell eine Möglichkeit in C++ gibt, einen vector mit unterschiedlichen Datentypen zu füllen.<br />
In Java gibt es den &quot;Vector&quot; und der kann mit versch. Datentypen gefüllt werden - gibt es soetwas in C++ ebenfalls?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/207287/vector-mit-unterschiedlichen-typen</link><generator>RSS for Node</generator><lastBuildDate>Tue, 13 Oct 2026 17:49:07 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/207287.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 05 Mar 2008 17:46:25 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to vector mit unterschiedlichen Typen? on Wed, 05 Mar 2008 17:46:25 GMT]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>ich wollte mal wissen, ob es generell eine Möglichkeit in C++ gibt, einen vector mit unterschiedlichen Datentypen zu füllen.<br />
In Java gibt es den &quot;Vector&quot; und der kann mit versch. Datentypen gefüllt werden - gibt es soetwas in C++ ebenfalls?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1468955</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1468955</guid><dc:creator><![CDATA[SeniiX]]></dc:creator><pubDate>Wed, 05 Mar 2008 17:46:25 GMT</pubDate></item><item><title><![CDATA[Reply to vector mit unterschiedlichen Typen? on Wed, 05 Mar 2008 17:55:23 GMT]]></title><description><![CDATA[<p>Du kannst den vector vom Typ void* machen.</p>
<p>std::vector&lt;void*&gt; enthält einen Zeiger auf irgendein Objekt</p>
<p>Bevor der Einspruch kommt wegen Zeigerfrickelei:<br />
Du kannst auch boost::any verwenden.</p>
<p>EDIT: Allerdings braucht man sowas in der Regel nicht...</p>
<p>Gruß,<br />
CSpille</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1468961</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1468961</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Wed, 05 Mar 2008 17:55:23 GMT</pubDate></item><item><title><![CDATA[Reply to vector mit unterschiedlichen Typen? on Wed, 05 Mar 2008 18:12:37 GMT]]></title><description><![CDATA[<p>Danke erstmal für die schnelle Antwort.</p>
<p>Inzwischen hab ich mir auch etwas überlegt. Und zwar habe ich eine Klassenhierarchie und meine Überlegung ist, dass ich einfach einen std::vector der Basisklasse erstelle und dann kann ich diesen mit Objekten der abgeleiteten Klassen füllen.<br />
Gibt es da irgendwelche Einwände?</p>
<p>So in etwa:</p>
<pre><code class="language-cpp">std::vector&lt;Basisklasse&gt; baseVec;
AbgeleiteteKlasse1 a;
AbgeleiteteKlasse2 b;
AbgeleiteteKlasse3 c;

baseVec.push_back(a);
baseVec.push_back(b);
baseVec.push_back(c);
</code></pre>
<p>Irgendwelche Risiken vorhanden? Der Compiler meldet keine Errors.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1468968</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1468968</guid><dc:creator><![CDATA[SeniiX]]></dc:creator><pubDate>Wed, 05 Mar 2008 18:12:37 GMT</pubDate></item><item><title><![CDATA[Reply to vector mit unterschiedlichen Typen? on Wed, 05 Mar 2008 18:14:33 GMT]]></title><description><![CDATA[<p>SeniiX schrieb:</p>
<blockquote>
<p>Danke erstmal für die schnelle Antwort.</p>
<p>Inzwischen hab ich mir auch etwas überlegt. Und zwar habe ich eine Klassenhierarchie und meine Überlegung ist, dass ich einfach einen std::vector der Basisklasse erstelle und dann kann ich diesen mit Objekten der abgeleiteten Klassen füllen.<br />
Gibt es da irgendwelche Einwände?</p>
<p>So in etwa:</p>
<pre><code class="language-cpp">std::vector&lt;Basisklasse&gt; baseVec;
AbgeleiteteKlasse1 a;
AbgeleiteteKlasse2 b;
AbgeleiteteKlasse3 c;

baseVec.push_back(a);
baseVec.push_back(b);
baseVec.push_back(c);
</code></pre>
<p>Irgendwelche Risiken vorhanden? Der Compiler meldet keine Errors.</p>
</blockquote>
<p>Finde ich die sauberere Lösung, als mit void*.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1468969</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1468969</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Wed, 05 Mar 2008 18:14:33 GMT</pubDate></item><item><title><![CDATA[Reply to vector mit unterschiedlichen Typen? on Wed, 05 Mar 2008 18:20:36 GMT]]></title><description><![CDATA[<p>wie wärs mit Polymorphie?</p>
<p>find ich noch saubeber, musst dich eben ums aufräumen kümmern...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1468975</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1468975</guid><dc:creator><![CDATA[Xantus]]></dc:creator><pubDate>Wed, 05 Mar 2008 18:20:36 GMT</pubDate></item><item><title><![CDATA[Reply to vector mit unterschiedlichen Typen? on Wed, 05 Mar 2008 18:22:31 GMT]]></title><description><![CDATA[<p>Xantus schrieb:</p>
<blockquote>
<p>wie wärs mit Polymorphie?</p>
<p>find ich noch saubeber, musst dich eben ums aufräumen kümmern...</p>
</blockquote>
<p>Er benutzt doch Polymorphie. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1468976</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1468976</guid><dc:creator><![CDATA[this-*gt*that]]></dc:creator><pubDate>Wed, 05 Mar 2008 18:22:31 GMT</pubDate></item><item><title><![CDATA[Reply to vector mit unterschiedlichen Typen? on Wed, 05 Mar 2008 18:30:56 GMT]]></title><description><![CDATA[<p>@this-&gt;that<br />
Also das denke ich nicht. Da er keine Zeiger verwendet oder Referezen verwendet. Siehe text an den OP.</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/10772">@SeniiX</a>:</p>
<p>Das mit dem vector und der Basisklasse kann nur dann funktionieren wenn du Zeiger auf die Basisklasse speicherst ansonsten kopierst du nämlich nur den Basisklassenteil deiner abgeleiteten klassen der rest ist dann futsch.</p>
<p>Natürlich musst du, wenn du zeiger verwendest darauf achten das du den Speicher später auch wieder ordnungsgemäß freigibst. Hierfür könntest du einen smart pointer<br />
verwenden der mit Polymorphie klar kommt (z.b. boost::shared_ptr&lt;&gt;)</p>
<p>BR<br />
Vinzenz</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1468984</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1468984</guid><dc:creator><![CDATA[evilissimo]]></dc:creator><pubDate>Wed, 05 Mar 2008 18:30:56 GMT</pubDate></item><item><title><![CDATA[Reply to vector mit unterschiedlichen Typen? on Wed, 05 Mar 2008 18:40:38 GMT]]></title><description><![CDATA[<p>evilissimo schrieb:</p>
<blockquote>
<p>Das mit dem vector und der Basisklasse kann nur dann funktionieren wenn du Zeiger auf die Basisklasse speicherst ansonsten kopierst du nämlich nur den Basisklassenteil deiner abgeleiteten klassen der rest ist dann futsch.</p>
<p>Natürlich musst du, wenn du zeiger verwendest darauf achten das du den Speicher später auch wieder ordnungsgemäß freigibst. Hierfür könntest du einen smart pointer<br />
verwenden der mit Polymorphie klar kommt (z.b. boost::shared_ptr&lt;&gt;)</p>
<p>BR<br />
Vinzenz</p>
</blockquote>
<p>Könntest du mir dazu ein kleines Code-Bsp geben oder es mir näher erläutern, damit ich es auch wirklich korrekt ausprogrammieren kann?!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1468989</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1468989</guid><dc:creator><![CDATA[SeniiX]]></dc:creator><pubDate>Wed, 05 Mar 2008 18:40:38 GMT</pubDate></item><item><title><![CDATA[Reply to vector mit unterschiedlichen Typen? on Wed, 05 Mar 2008 18:58:27 GMT]]></title><description><![CDATA[<p>Das Problem ist folgendes:</p>
<p>Wenn du eine Basisklasse B und eine Unterklasse C hast und jetzt eine Instanz vom Typ B mittels C instantiierst:<br />
B b(c);<br />
dann geht das zwar, aber es werden natürlich nur die B-Member von c nach b kopiert (die C Member kennt der B Copyctor ja garnicht). Das nennt man Slicing und ist unschön.</p>
<p>Ferner hast du in deinem Beispiel keine Polymorphie. Sagen wir B hat eine Methode foo(), die in C überschrieben wird.<br />
Wenn du jetzt das machst:<br />
std::vector&lt;B&gt; v;<br />
v.add(c);<br />
und dann v[0].foo(); (sieht wohl irgendwie so aus, kenne die Syntax vom vector nicht auswendig)<br />
so wird IMMER das foo() der Basisklasse B aufgerufen, auch wenn du in Wirklichkeit eine Instanz vom Typ C ansprichst.</p>
<p>Für Polymorphie brauchst du also Zeiger:<br />
std::vector&lt;B*&gt; v;<br />
v.add(new C(...));<br />
v.add(new B(...); usw.</p>
<p>Dann funktioniert Polymorphie. Allerdings musst du bei einigen Algorithmen auf Containern aufpassen und auch selber den reservierten Speicher freigeben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1468997</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1468997</guid><dc:creator><![CDATA[this-*gt*that]]></dc:creator><pubDate>Wed, 05 Mar 2008 18:58:27 GMT</pubDate></item><item><title><![CDATA[Reply to vector mit unterschiedlichen Typen? on Wed, 05 Mar 2008 19:06:50 GMT]]></title><description><![CDATA[<p>Typen:</p>
<pre><code class="language-cpp">struct Basis{ virtual int getValue() const { return 0; } };
struct Abgeleitet1 : Basis { virtual int getValue() const { return 1; } };
struct Abgeleitet2 : Basis { virtual int getValue() const { return 2; } };
</code></pre>
<p>Lösung 1:<br />
Zeiger selber verwalten<br />
- Sehr aufwendig<br />
- Fehleranfällig<br />
Und daher würde ich es auch als unsauber einstufen</p>
<pre><code class="language-cpp">std::vector&lt;Basis*&gt; basis_vec;
basis_vec.push_back(new Abgeleitet1());
basis_vec.push_back(new Abgeleitet2());
basis_vec.push_back(new Basis());

// Erst Speicher der Zeiger freigeben
for(std::vector&lt;Basis*&gt;::iterator it = basis_vec.begin(), end = basis_vec.end();    it != end; ++it)
  delete *it;
// Dann zeiger löschen
basis_vec.clear();
</code></pre>
<p>Lösung2:<br />
boost::shared_ptr&lt;&gt; verwenden<br />
Ist immer noch sehr aufwendig und verursacht overhead (wegen den Smartpointern) aber immerhin weniger fehleranfällig für speicherlecks.</p>
<pre><code class="language-cpp">std::vector&lt;boost::shared_ptr&lt;Basis&gt; &gt; basis_vec;
basis_vec.push_back(boost::shared_ptr&lt;Basis&gt;(new Abgeleitet1()));
basis_vec.push_back(boost::shared_ptr&lt;Basis&gt;(new Abgeleitet2()));
basis_vec.push_back(boost::shared_ptr&lt;Basis&gt;(new Basis()));

basis_vec.clear();
</code></pre>
<p>Lösung3:<br />
Sauberste Lösung mit dem wenigsten overhead:</p>
<pre><code class="language-cpp">// Braucht #include &lt;boost/ptr_container/ptr_vector.hpp&gt;
boost::ptr_vector&lt;Basis&gt; basis_vec;
basis_vec.push_back(new Abgeleitet1());
basis_vec.push_back(new Abgeleitet2());
basis_vec.push_back(new Basis());

basis_vec.clear();
</code></pre>
<p>BR<br />
Vinzenz</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1469000</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1469000</guid><dc:creator><![CDATA[evilissimo]]></dc:creator><pubDate>Wed, 05 Mar 2008 19:06:50 GMT</pubDate></item><item><title><![CDATA[Reply to vector mit unterschiedlichen Typen? on Wed, 05 Mar 2008 19:11:50 GMT]]></title><description><![CDATA[<p>Braucht man das clear() zwingend? Sowas sollte ja eigentlich der Dtor machen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1469007</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1469007</guid><dc:creator><![CDATA[this-*gt*that]]></dc:creator><pubDate>Wed, 05 Mar 2008 19:11:50 GMT</pubDate></item><item><title><![CDATA[Reply to vector mit unterschiedlichen Typen? on Wed, 05 Mar 2008 19:19:26 GMT]]></title><description><![CDATA[<p>this-&gt;that schrieb:</p>
<blockquote>
<p>Braucht man das clear() zwingend? Sowas sollte ja eigentlich der Dtor machen.</p>
</blockquote>
<p>Nein das war nur ein Beispiel um zu verdeutlichen was passieren muss wenn man daten aus dem vector löscht. Natürlich macht das der Destruktor.</p>
<p>Aber der Destruktor gibt bei Lösung 1 eben nicht den Speicher der Zeiger frei. (Was dir sicherlich klar ist :))</p>
<p>BR<br />
Vinzenz</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1469013</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1469013</guid><dc:creator><![CDATA[evilissimo]]></dc:creator><pubDate>Wed, 05 Mar 2008 19:19:26 GMT</pubDate></item><item><title><![CDATA[Reply to vector mit unterschiedlichen Typen? on Wed, 05 Mar 2008 19:24:09 GMT]]></title><description><![CDATA[<p>Vielen vielen Dank, ich werde das mal so versuchen zu implementieren und bei Fragen komm ich eh wieder angekrochen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1469019</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1469019</guid><dc:creator><![CDATA[SeniiX]]></dc:creator><pubDate>Wed, 05 Mar 2008 19:24:09 GMT</pubDate></item><item><title><![CDATA[Reply to vector mit unterschiedlichen Typen? on Wed, 05 Mar 2008 19:25:44 GMT]]></title><description><![CDATA[<p>SeniiX schrieb:</p>
<blockquote>
<p>Vielen vielen Dank, ich werde das mal so versuchen zu implementieren und bei Fragen komm ich eh wieder angekrochen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /></p>
</blockquote>
<p>Macht doch nichts, wenn wir dir hier nicht Kompetent zu deinen Fragen helfen können, wo sonst? <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>BR<br />
Vinzenz</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1469020</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1469020</guid><dc:creator><![CDATA[evilissimo]]></dc:creator><pubDate>Wed, 05 Mar 2008 19:25:44 GMT</pubDate></item><item><title><![CDATA[Reply to vector mit unterschiedlichen Typen? on Wed, 05 Mar 2008 19:51:41 GMT]]></title><description><![CDATA[<p>Wenn die Zahl der Typen, die du in dem Vektor speichern willst eine „natürliche“ Begrenzung hat, dann ist auch Boost.Variant erwähnenswert.</p>
<p>Der Vorteil daran ist, dass es mit großer Wahrscheinlichkeit schneller ist als any, die Objekte auch tatsächlich im Vektor liegen (und nicht irgendwo auf dem Heap verstreut und bezeigt) und du mit einem (sehr intuitiv zu implementierenden) Visitor und std::for_each sehr schön die Daten weiterverarbeiten kannst.</p>
<p>Der Nachteil ist, dass eben nur endlich viele Typen möglich sind und jedes Variant so groß ist, wie der größte darin speicherbare Typ.</p>
<p>Konkret hab ich das mal für einen Midiparser verwendet, wobei ich die verschiedenen Midi-Ereignisse als einzelne Klassen implementiert habe, die von einander abgeleitet waren. Eine Spur wurde dann (relativ einfach) in einen Vektor mit solchen Variants geparst.</p>
<p>Um nun die Spur zu verwenden, reicht es, einen passenden Visitor zu schreiben (der den operator() für geeignete Ereignisse überlädt (zb meta_event oder key_press), wobei auch die Vererbung berücksichtigt wird. Man kann beispielsweise recht einfach Filter schreiben, indem man nur für key_event (was key_press, key_release und key_aftertouch Basisklasse ist) o.ä. überlädt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1469040</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1469040</guid><dc:creator><![CDATA[.filmor]]></dc:creator><pubDate>Wed, 05 Mar 2008 19:51:41 GMT</pubDate></item><item><title><![CDATA[Reply to vector mit unterschiedlichen Typen? on Thu, 06 Mar 2008 07:00:33 GMT]]></title><description><![CDATA[<p>Kann ich 2 boost::ptr_vector normal mit dem =-Operator gleichsetzen?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1469137</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1469137</guid><dc:creator><![CDATA[SeniiX]]></dc:creator><pubDate>Thu, 06 Mar 2008 07:00:33 GMT</pubDate></item><item><title><![CDATA[Reply to vector mit unterschiedlichen Typen? on Thu, 06 Mar 2008 10:21:10 GMT]]></title><description><![CDATA[<p>Da ich beim Gleichsetzen per operator= immer einen Error bekomme, habe ich mir mal folgendes überlegt:</p>
<p>Typen:</p>
<pre><code class="language-cpp">class B
{
   private:
      int Age;

   public:
      B( void ) { this-&gt;Age = 0; }
      ~B( void ) {}

      int getAge( void ) { return this-&gt;Age; }
      void setAge( const int &amp;aAge) { this-&gt;Age = aAge; }

      virtual void speak( void ) { std::cout &lt;&lt; &quot;B speaking&quot; &lt;&lt; std::endl; }
};

class A1 : public B
{
   public:
      A1( void ) {}
      ~A1( void ) {}

      virtual void speak( void ) { std::cout &lt;&lt; &quot;A1 speaking&quot; &lt;&lt; std::endl; }
};

class A2 : public B
{
   public:
      A2( void ) {}
      ~A2( void ) {}

      virtual void speak( void ) { std::cout &lt;&lt; &quot;A2 speaking&quot; &lt;&lt; std::endl; }
};
</code></pre>
<p>Versuch den boost::ptr_vector zu kopieren:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;cstdlib&gt;

#include &lt;boost/ptr_container/ptr_vector.hpp&gt;

int main(int argc, char **argv)
{
   boost::ptr_vector&lt;B&gt; BVec1, BVec2;

   BVec1.push_back(new A1());
   BVec1.push_back(new A2());
   BVec1.push_back(new A1());

   for(int i=0; i&lt;BVec1.size(); i++)
      BVec2.push_back(&amp;BVec1[i]);

   for(int i=0; i&lt;BVec1.size(); i++)
      BVec2[i].speak();

   BVec1.clear();
   BVec2.clear();

   return 0;
}
</code></pre>
<p>Da sich mein Programm jedoch immer aufhängt (am Ende) hab ich nochmal in der Dokumtation der boost library nachgeschaut und die Funktion &quot;assign&quot; gefunden und folgendes probiert:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;cstdlib&gt;

#include &lt;boost/ptr_container/ptr_vector.hpp&gt;

int main(int argc, char **argv)
{
   boost::ptr_vector&lt;B&gt; BVec1, BVec2;

   BVec1.push_back(new A1());
   BVec1.push_back(new A2());
   BVec1.push_back(new A1());

   BVec2.assign(BVec1.begin(), BVec1.begin());

   for(int i=0; i&lt;BVec1.size(); i++)
      BVec2[i].speak();

   BVec1.clear();
   BVec2.clear();

   return 0;
}
</code></pre>
<p>Dieses Programm stürzt zwar nicht ab, allerdings kopiert &quot;assign&quot; irgendwie falsch, da ich bei der Ausgabe über &quot;speak()&quot; immer die Ausgabe &quot;B speaks&quot; bekomme, also die Funktion der Basisklasse aufgerufen wird.</p>
<p>Kann mir jemand sagen, wie ich richtig zwei boost::ptr_vector&lt;B&gt; gleichsetzen kann? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1469212</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1469212</guid><dc:creator><![CDATA[SeniiX]]></dc:creator><pubDate>Thu, 06 Mar 2008 10:21:10 GMT</pubDate></item><item><title><![CDATA[Reply to vector mit unterschiedlichen Typen? on Thu, 06 Mar 2008 10:29:39 GMT]]></title><description><![CDATA[<p>Dir ist anscheinend nicht klar, dass ptr_vector die Zeiger beim Zerstören auch löscht (das ist ja u.a. der Sinn der Sache). Damit ist auch der erste Fall klar: Beide vectoren enthalten nachher dieselben Zeiger, d.h. die Objekte werden alle doppelt gelöscht.</p>
<p>Im zweiten Fall wird der ptr_vector wohl versuchen, die Objekte via new_clone zu kopieren, und die Standardimplementierung von new_clone läuft auf new B hinaus, da der vector zur Kompilierzeit nicht weiß, welche Typen tatsächlich gespeichert wurden. Dafür müsstest Du die Funktion B* new_clone( const B&amp; ) anbieten und dort tatsächlich einen Klon von A1, A2 ... zurückgeben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1469223</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1469223</guid><dc:creator><![CDATA[LordJaxom]]></dc:creator><pubDate>Thu, 06 Mar 2008 10:29:39 GMT</pubDate></item><item><title><![CDATA[Reply to vector mit unterschiedlichen Typen? on Thu, 06 Mar 2008 10:45:05 GMT]]></title><description><![CDATA[<p>LordJaxom schrieb:</p>
<blockquote>
<p>Dafür müsstest Du die Funktion B* new_clone( const B&amp; ) anbieten und dort tatsächlich einen Klon von A1, A2 ... zurückgeben.</p>
</blockquote>
<p>Danke erstmal für die schnelle und hilfreiche Antwort - echt super hier <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>Ich habe deinen Rat befolgt und folgende Funktion &quot;new_clone&quot; ausprogrammiert:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;cstdlib&gt;
#include &lt;typeinfo&gt;    // für Typenüberprüfung

#include &lt;boost/ptr_container/ptr_vector.hpp&gt;

B *new_clone(const B &amp;b)
{
   if(typeid(b) == typeid(A1))
      return new A1();

   else if(typeid(b) == typeid(A2))
      return new A2();

   else if(typeid(b) == typeid(B))
      return new B();

   else
      return NULL;
}

int main(int argc, char **argv)
{
   boost::ptr_vector&lt;B&gt; BVec1, BVec2;

   BVec1.push_back(new A1());
   BVec1.push_back(new A2());
   BVec1.push_back(new A1());

   for(int i=0; i&lt;BVec1.size(); i++)
      BVec2.push_back(new_clone(BVec1[i]));

   for(int i=0; i&lt;BVec2.size(); i++)
      BVec2.speak();

   BVec1.clear();
   BVec2.clear();

   return 0;
}
</code></pre>
<p>Mit dieser Funktion &quot;new_clone&quot; funktioniert es. Meine Frage ist nurmehr, ob ich sie verbessern kann bzw. ob sie Risiken hat?</p>
<p>Danke schonmal für die Antwort <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/1469235</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1469235</guid><dc:creator><![CDATA[SeniiX]]></dc:creator><pubDate>Thu, 06 Mar 2008 10:45:05 GMT</pubDate></item><item><title><![CDATA[Reply to vector mit unterschiedlichen Typen? on Thu, 06 Mar 2008 11:44:28 GMT]]></title><description><![CDATA[<p>Ok, beim Austesten der &quot;new_clone&quot;-Funktion ist mir jetzt selbst bereits ein Fehler aufgefallen. Angenommen wir haben folgende Typen:</p>
<pre><code class="language-cpp">class B
{
   protected:
      int Age;

   public:
      B( void ) { this-&gt;Age = 0; }
      B( const int &amp;aAge) { this-&gt;Age = aAge; }
      ~B( void ) {}

      int getAge( void ) { return this-&gt;Age; }
      void setAge( const int &amp;aAge) { this-&gt;Age = aAge; }

      virtual void speak( void ) { std::cout &lt;&lt; &quot;B speaking&quot; &lt;&lt; std::endl; }
};

class A1 : public B
{
   private:
      int Weight;

   public:
      A1( void ) {}
      A1( const int &amp;aWeight ) { this-&gt;Weight = aWeight; }
      ~A1( void ) {}

      int getWeight( void ) { return this-&gt;Weight; }
      void setWeight( const int &amp;aWeight ) { this-&gt;Weight = aWeight; }

      virtual void speak( void ) { std::cout &lt;&lt; &quot;A1 speaking&quot; &lt;&lt; std::endl; }
};

class A2 : public B
{
   private:
      int Height;

   public:
      A2( void ) {}
      A2( const int &amp;aHeight ) { this-&gt;Height = aHeight; }
      ~A2( void ) {}

      int getHeight( void ) { return this-&gt;Height; }
      void setHeight( const int &amp;aHeight ) { this-&gt;Height = aHeight; }

      virtual void speak( void ) { std::cout &lt;&lt; &quot;A2 speaking&quot; &lt;&lt; std::endl; }
};
</code></pre>
<p>Wenn ich nun Objekte mit bestimmten Werten initialisiere und in den boost::ptr_vector fülle habe ich ein Problem bei der new_clone-Funktion.</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;cstdlib&gt;
#include &lt;typeinfo&gt;    // für Typenüberprüfung

#include &lt;boost/ptr_container/ptr_vector.hpp&gt;

B *new_clone(const B &amp;b)
{
   if(typeid(b) == typeid(A1))
      return new A1();

   else if(typeid(b) == typeid(A2))
      return new A2();

   else if(typeid(b) == typeid(B))
      return new B();

   else
      return NULL;
}

int main(int argc, char **argv)
{
   boost::ptr_vector&lt;B&gt; BVec1, BVec2;
   const int init1 = 15, init2 = 20;

   BVec1.push_back(new A1());
   BVec1.push_back(new A2());
   BVec1.push_back(new A1(init1));
   BVec1.push_back(new A2(init2));

   for(int i=0; i&lt;BVec1.size(); i++)
      BVec2.push_back(new_clone(BVec1[i]));

   for(int i=0; i&lt;BVec2.size(); i++)
      BVec2[i].speak();

   BVec1.clear();
   BVec2.clear();

   return 0;
}
</code></pre>
<p>Da müsste ich wieder eine Unterscheidung treffen, allerdings vorher die B-Objekte in A1- bzw. A2-Objekte konvertieren um ihre Werte Weight bzw. Height per getWeight() oder getHeight() überprüfen zu können.</p>
<p>Mein erster Gedanke war ein einfacher Cast:</p>
<pre><code class="language-cpp">B *new_clone(const B &amp;b)
{
   if(typeid(b) == typeid(A1))
   {
      return new A1( ((A1)(b)).getWeight() );
   }

   else if(typeid(b) == typeid(A2))
   {
      return new A2( ((A2)(b)).getHeight() );
   }

   else if(typeid(b) == typeid(B))
   {
      return new B( ((B)(b)).getAge() );
   }

   else
      return NULL;
}
</code></pre>
<p>Allerdings finde ich das nicht schön - hat jemand einen hilfreichen Vorschlag für mich? <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="😞"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1469278</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1469278</guid><dc:creator><![CDATA[SeniiX]]></dc:creator><pubDate>Thu, 06 Mar 2008 11:44:28 GMT</pubDate></item><item><title><![CDATA[Reply to vector mit unterschiedlichen Typen? on Thu, 06 Mar 2008 12:08:44 GMT]]></title><description><![CDATA[<p>Copy-Constructor?</p>
<pre><code class="language-cpp">return new A1( dynamic_cast&lt; A1&amp; &gt;( b ) );
</code></pre>
<p>Gedacht ist diese new_clone Funktion allerdings eher für virtuelles Klonen. Damit sparst Du Dir auch die (u.U. sehr langsamen) typeid-Vergleiche:</p>
<pre><code class="language-cpp">class B
{
    virtual B* clone();
};

class A1
{
    virtual A1* clone() { return new A1( *this ); }
};

class A2
{
    virtual A2* clone() { return new A2( *this ); }
};

B* new_clone( B const&amp; b )
{
    return b.clone();
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1469303</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1469303</guid><dc:creator><![CDATA[LordJaxom]]></dc:creator><pubDate>Thu, 06 Mar 2008 12:08:44 GMT</pubDate></item><item><title><![CDATA[Reply to vector mit unterschiedlichen Typen? on Thu, 06 Mar 2008 12:15:43 GMT]]></title><description><![CDATA[<p>LordJaxom schrieb:</p>
<blockquote>
<p>Copy-Constructor?</p>
<pre><code class="language-cpp">return new A1( dynamic_cast&lt; A1&amp; &gt;( b ) );
</code></pre>
</blockquote>
<p>der richtige cast wäre <code>static_cast</code> , vor allem weil ja sowieso schon nach dem <code>typeid</code> klar ist, um welchen dynamischen typ es sich handelt. (mit <code>dynamic_cast</code> wäre so ein konstrukt besser:</p>
<pre><code class="language-cpp">Base* new_clone (Base* b)
{
  if (Derived* d = dynamic_cast&lt;Derived*&gt;(b))
  {
    return new Derived(*d);
  }
  //...
}
</code></pre>
<p>)</p>
<p>warum &quot;langsame typeid-vergleiche&quot;?<br />
(natürlich ist deine lösung (&quot;virtueller copy-ctor&quot; clone) am elegantesten)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1469309</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1469309</guid><dc:creator><![CDATA[queer_boy]]></dc:creator><pubDate>Thu, 06 Mar 2008 12:15:43 GMT</pubDate></item><item><title><![CDATA[Reply to vector mit unterschiedlichen Typen? on Thu, 06 Mar 2008 12:20:17 GMT]]></title><description><![CDATA[<p>queer_boy schrieb:</p>
<blockquote>
<p>der richtige cast wäre <code>static_cast</code> , vor allem weil ja sowieso schon nach dem <code>typeid</code> klar ist, um welchen dynamischen typ es sich handelt. (mit <code>dynamic_cast</code> wäre so ein konstrukt besser:</p>
</blockquote>
<p>Hast natürlich recht, der dynamische hat hier mehr Overhead.</p>
<blockquote>
<p>warum langsame typeid-vergleiche?</p>
</blockquote>
<p>Weil ich mindestens eine Implementierung kenne (wenngleich die auch veraltet ist), die in type_info::operator== Stringvergleiche macht. Der virtuelle Aufruf ist nur eine Indirektion.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1469311</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1469311</guid><dc:creator><![CDATA[LordJaxom]]></dc:creator><pubDate>Thu, 06 Mar 2008 12:20:17 GMT</pubDate></item><item><title><![CDATA[Reply to vector mit unterschiedlichen Typen? on Thu, 06 Mar 2008 13:13:07 GMT]]></title><description><![CDATA[<p>Danke für eure Hilfe. Ich habe es genau so implementiert (die Lösung mit dem Copy-Ctor), einziger Unterschied ist, dass ich das Schlüsselwort const weggelassen habe, weil ich einen Error</p>
<pre><code>passing 'const B' as 'this' argument of 'virtual B* B::clone()' discards qualifiers
</code></pre>
<p>bekommen habe. Wenn noch jemand so nett ist und mir erläutert, wieso const in diesem Zusammenhang falsch ist, wäre ich glücklich fürs Erste <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/1469376</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1469376</guid><dc:creator><![CDATA[SeniiX]]></dc:creator><pubDate>Thu, 06 Mar 2008 13:13:07 GMT</pubDate></item><item><title><![CDATA[Reply to vector mit unterschiedlichen Typen? on Thu, 06 Mar 2008 13:48:06 GMT]]></title><description><![CDATA[<p>SeniiX schrieb:</p>
<blockquote>
<p>Danke für eure Hilfe. Ich habe es genau so implementiert (die Lösung mit dem Copy-Ctor), einziger Unterschied ist, dass ich das Schlüsselwort const weggelassen habe, weil ich einen Error</p>
<pre><code>passing 'const B' as 'this' argument of 'virtual B* B::clone()' discards qualifiers
</code></pre>
<p>bekommen habe. Wenn noch jemand so nett ist und mir erläutert, wieso const in diesem Zusammenhang falsch ist, wäre ich glücklich fürs Erste <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>
</blockquote>
<p>du versuchst wahrscheinlich, eine nicht-konstante memberfunktion für ein konstantes objekt aufzurufen. da <code>clone</code> keine änderungen am objekt vornimmt, wäre es wahrscheinlich besser, bevor du überall <code>const</code> weglässt, clone eben zu einer konstanten memberfunktion zu machen:</p>
<pre><code class="language-cpp">class Foo
{
public:
   Foo* clone () const { return new Foo(*this); }
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1469402</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1469402</guid><dc:creator><![CDATA[queer_boy]]></dc:creator><pubDate>Thu, 06 Mar 2008 13:48:06 GMT</pubDate></item><item><title><![CDATA[Reply to vector mit unterschiedlichen Typen? on Thu, 06 Mar 2008 14:02:05 GMT]]></title><description><![CDATA[<p>LordJaxom schrieb:</p>
<blockquote>
<p>Copy-Constructor?</p>
<pre><code class="language-cpp">return new A1( dynamic_cast&lt; A1&amp; &gt;( b ) );
</code></pre>
</blockquote>
<p>würde hier dem cast ein template vorziehen:</p>
<pre><code class="language-cpp">template&lt;class T&gt;
T* make_clone(const T&amp; t)
{
	return new T(t);
}
</code></pre>
<p>Und in den Childklassen dann:</p>
<pre><code class="language-cpp">class A2
{
    virtual A2* clone() { return make_clone( *this ); }
};
</code></pre>
<p>phlox</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1469413</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1469413</guid><dc:creator><![CDATA[phlox81]]></dc:creator><pubDate>Thu, 06 Mar 2008 14:02:05 GMT</pubDate></item></channel></rss>