<?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[Muss ich Vectoren serialisieren oder geht das auch irgendwie einfacher?]]></title><description><![CDATA[<p>Hallo Community,</p>
<p>habe mal wieder eine Frage, ob ich das richtig verstanden habe.</p>
<p>Ich habe eine Klasse die mehrere Unterklassen beinhaltet. In diesen Klassen befinden sich zum Teil Vectoren oder auch doppelt verschachtelte Vectoren.</p>
<p>Nun möchte ich das ganze speichern und ich bekomme beim Speichern zwar keinen Fehler aber beim Laden merke ich das die Daten in den Vectoren fehlen.</p>
<p>Ich habe hier im Forum gelesen, dass ich die Daten wohl erst serialisieren muß um sie in einem Stream zu speichern.</p>
<p>Bisher habe ich das in der C Form getan</p>
<pre><code>fwrite(User, sizeof(CKomponenten),1,fp);
</code></pre>
<p>aber da werden wohl nur die Variablen gespeichert und nicht die Vectoren.</p>
<p>Heißt das nun, dass ich alle Unterklassen durchgehen muß und die jeweiligen Vectoren serialisieren muß und wenn ja, wie mache ich das?</p>
<p>Bei so einer Struktur:</p>
<pre><code class="language-cpp">class CKomponente
{
 private: // Private Variablen

 public:
  CKomponente(){};
  ~CKomponente(){};

  class C2Freq BauteilA;
  class C2Freq BauteilB;
  class C1UOFreq BauteilC;
  ...
};

class C2Freq
{
 private: // Private Variablen

 public:
  C2Freq(){};
  ~C2Freq(){};

  class CElement Eigenschaft;
  class CFreq Freq[2];
  class CMessContainer[2];
};

class CMessContainer
{
 private:

 public:
 CMessContainer();                      // Konstruktor
 ~CMessContainer();                     // Destruktor

 // Datencontainer für alle Messreihen
 vector &lt;vector &lt;CMessung&gt; &gt; Messung;
};

class CMessung
{
 private:
 double anzahl;                 // Anzahl Messwerte
 double summe;                  // Summe aller Messwerte
 double quadsumme;              // Summe im Quadrat
 double mittelwert;             // Mittelwert
 double quadmittel;             // Quadrat des Mittelwerts
 double standardabweichung;     // Standardabweichung
 double standardabweichung1;    // Standardabweichung (n-1)
 double varianz;                // Varianz
 double _1sig;                  // Sigma 1
 double _2sig;                  // Sigma 2
 double _3sig;                  // Sigma 3
 double rms;                    // RMS
 double min;                    // kleinster Wert
 double max;                    // größter Wert
 double amax;                   // Maximum Betrag

 // Initialisierung
 int Init(void);

 public:
 CMessung();                    // Konstruktor
 ~CMessung();                   // Destruktor

 // Vector für Werteaufnahme
 vector &lt;float&gt; Wert;
};
</code></pre>
<p>Was ich bis jetzt gefunden habe, war von CStoll dieses Beispiel für eine einfache Struktur, aber wie bekomme ich das bei den ganzen Vectoren hin?</p>
<pre><code>ostream&amp; operator&lt;&lt;(ostream&amp; f,const Daten&amp; d)
{
  f&lt;&lt;d.Name&lt;&lt;&quot;-&quot;&lt;&lt;d.Pfad&lt;&lt;&quot;-&quot;&lt;&lt;d.Groesse;
  return f;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/208247/muss-ich-vectoren-serialisieren-oder-geht-das-auch-irgendwie-einfacher</link><generator>RSS for Node</generator><lastBuildDate>Mon, 12 Oct 2026 01:55:58 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/208247.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 16 Mar 2008 18:38:32 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Muss ich Vectoren serialisieren oder geht das auch irgendwie einfacher? on Sun, 16 Mar 2008 18:38:32 GMT]]></title><description><![CDATA[<p>Hallo Community,</p>
<p>habe mal wieder eine Frage, ob ich das richtig verstanden habe.</p>
<p>Ich habe eine Klasse die mehrere Unterklassen beinhaltet. In diesen Klassen befinden sich zum Teil Vectoren oder auch doppelt verschachtelte Vectoren.</p>
<p>Nun möchte ich das ganze speichern und ich bekomme beim Speichern zwar keinen Fehler aber beim Laden merke ich das die Daten in den Vectoren fehlen.</p>
<p>Ich habe hier im Forum gelesen, dass ich die Daten wohl erst serialisieren muß um sie in einem Stream zu speichern.</p>
<p>Bisher habe ich das in der C Form getan</p>
<pre><code>fwrite(User, sizeof(CKomponenten),1,fp);
</code></pre>
<p>aber da werden wohl nur die Variablen gespeichert und nicht die Vectoren.</p>
<p>Heißt das nun, dass ich alle Unterklassen durchgehen muß und die jeweiligen Vectoren serialisieren muß und wenn ja, wie mache ich das?</p>
<p>Bei so einer Struktur:</p>
<pre><code class="language-cpp">class CKomponente
{
 private: // Private Variablen

 public:
  CKomponente(){};
  ~CKomponente(){};

  class C2Freq BauteilA;
  class C2Freq BauteilB;
  class C1UOFreq BauteilC;
  ...
};

class C2Freq
{
 private: // Private Variablen

 public:
  C2Freq(){};
  ~C2Freq(){};

  class CElement Eigenschaft;
  class CFreq Freq[2];
  class CMessContainer[2];
};

class CMessContainer
{
 private:

 public:
 CMessContainer();                      // Konstruktor
 ~CMessContainer();                     // Destruktor

 // Datencontainer für alle Messreihen
 vector &lt;vector &lt;CMessung&gt; &gt; Messung;
};

class CMessung
{
 private:
 double anzahl;                 // Anzahl Messwerte
 double summe;                  // Summe aller Messwerte
 double quadsumme;              // Summe im Quadrat
 double mittelwert;             // Mittelwert
 double quadmittel;             // Quadrat des Mittelwerts
 double standardabweichung;     // Standardabweichung
 double standardabweichung1;    // Standardabweichung (n-1)
 double varianz;                // Varianz
 double _1sig;                  // Sigma 1
 double _2sig;                  // Sigma 2
 double _3sig;                  // Sigma 3
 double rms;                    // RMS
 double min;                    // kleinster Wert
 double max;                    // größter Wert
 double amax;                   // Maximum Betrag

 // Initialisierung
 int Init(void);

 public:
 CMessung();                    // Konstruktor
 ~CMessung();                   // Destruktor

 // Vector für Werteaufnahme
 vector &lt;float&gt; Wert;
};
</code></pre>
<p>Was ich bis jetzt gefunden habe, war von CStoll dieses Beispiel für eine einfache Struktur, aber wie bekomme ich das bei den ganzen Vectoren hin?</p>
<pre><code>ostream&amp; operator&lt;&lt;(ostream&amp; f,const Daten&amp; d)
{
  f&lt;&lt;d.Name&lt;&lt;&quot;-&quot;&lt;&lt;d.Pfad&lt;&lt;&quot;-&quot;&lt;&lt;d.Groesse;
  return f;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1475420</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1475420</guid><dc:creator><![CDATA[egcactus]]></dc:creator><pubDate>Sun, 16 Mar 2008 18:38:32 GMT</pubDate></item><item><title><![CDATA[Reply to Muss ich Vectoren serialisieren oder geht das auch irgendwie einfacher? on Tue, 18 Mar 2008 11:12:38 GMT]]></title><description><![CDATA[<p>Ich habe mal jeder Klasse eine Speichern Funktion spendiert in der ich versuche die Vectoren nacheinander zu speichern und in der Hoffnung, dass ich die Daten irgendwie in eine Datei speichern kann in dem ich die einzelnen Teile aneinander hänge.</p>
<p>Aber so richtig will das nicht Klappen und wie ich den zweidimensionalen Vector gespeichert bekomme weiß ich einfach nicht und alles was ich finde ist immer für eindimensionale Vectoren.</p>
<p>Vielleicht hat ja jemand einen Tip.</p>
<p>Grüße<br />
egcactus</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1476454</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1476454</guid><dc:creator><![CDATA[egcactus]]></dc:creator><pubDate>Tue, 18 Mar 2008 11:12:38 GMT</pubDate></item><item><title><![CDATA[Reply to Muss ich Vectoren serialisieren oder geht das auch irgendwie einfacher? on Tue, 18 Mar 2008 11:46:33 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">struct XYZ
{
    double                  a;
    vector&lt;int&gt;             b;
    vector&lt; vector&lt;float&gt; &gt; c;
};

ostream&amp; operator&lt;&lt;( ostream&amp; f, const XYZ&amp; x )
{
    f &lt;&lt; x.a;

    f &lt;&lt; x.b.size();
    for ( vector&lt;int&gt;::const_iterator iter=x.b.begin(); iter!=x.b.end(); iter++ )
        f &lt;&lt; *iter;

    f &lt;&lt; x.c.size();
    for ( vector&lt; vector&lt;float&gt; &gt;::const_iterator outerIter=x.c.begin(); outerIter!=x.c.end(); outerIter++ )
    {
        f &lt;&lt; outerIter-&gt;size();
        for ( vector&lt;float&gt;::const_iterator innerIter=outerIter-&gt;begin(); innerIter!=outerIter-&gt;end(); innerIter++ )
            f &lt;&lt; *innerIter;
    }
    return f;
}

istream&amp; operator&gt;&gt;( istream&amp; f, XYZ&amp; x )
{
    f &gt;&gt; x.a;

    vector&lt;int&gt;::size_type b_size;
    f &gt;&gt; b_size;
    x.b.reserve( b_size );
    for ( vector&lt;int&gt;::size_type i=0; i&lt;b_size; i++ )
    {
        int val;
        f &gt;&gt; val;
        x.b.push_back( val );
    }

    vector&lt; vector&lt;float&gt; &gt;::size_type c_outer_size;
    f &gt;&gt; c_outer_size;
    x.c.resize( c_outer_size );
    for ( vector&lt; vector&lt;float&gt; &gt;::size_type i=0; i&lt;c_outer_size; i++ )
    {
        vector&lt;float&gt;::size_type arr_size;
        f &gt;&gt; arr_size;

        vector&lt;float&gt; arr;
        arr.resize( arr_size );

        for ( vector&lt; vector&lt;float&gt; &gt;::size_type j=0; j&lt;arr_size; j++ )
        {
            float val;
            f &gt;&gt; val;
            arr.push_back( val );
        }

        x.c.push_back( arr );
    }
    return f;
}
</code></pre>
<p>Ohne Gewähr und Implementationsabhängig <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/1476483</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1476483</guid><dc:creator><![CDATA[Badestrand]]></dc:creator><pubDate>Tue, 18 Mar 2008 11:46:33 GMT</pubDate></item><item><title><![CDATA[Reply to Muss ich Vectoren serialisieren oder geht das auch irgendwie einfacher? on Wed, 19 Mar 2008 08:13:30 GMT]]></title><description><![CDATA[<p>Hallo Badestrand,</p>
<p>danke für diesen Programmauszug. Kann ich dir kurz erklären wie ich das verstehe, nur damit ich das in meinem Projekt auch richtig mache und richtig anwende.</p>
<p>Struktur ist klar.</p>
<pre><code>ostream&amp; operator&lt;&lt;( ostream&amp; f, const XYZ&amp; x )
</code></pre>
<p>Hier beginnst du die Variable a in f zu schreiben, danach übergibst du die größe von vector b in f und gehst anschließend durch den vector &lt;int&gt; b und übergibst den inhalt an f.</p>
<p><strong>const_iterator</strong> bedeutet wohl, dass er stets den konstanten Abstand von int einhalten soll.</p>
<p>danach machst du das selbe mit dem vector &lt;vector &lt;float&gt; &gt;c;<br />
und gibst f zurück.</p>
<p>Einlesefunktion<br />
istream&amp; operator&gt;&gt;( istream&amp; f, XYZ&amp; x )</p>
<p>aus f wird a eingelesen, danach bestimmst du du die größe von b. Das size_type ist wohl eine bestimmter Datentyp der einem die Größe sagen kann, den wir in die Variable f geschrieben haben.</p>
<p>vector&lt;int&gt;::<strong>size_type b_size</strong>;</p>
<p>danach reservieren wir entsprechend viel Platz. und lesen unsere Int Elemente ein. ok soweit, das machen wir auch mit dem verschateltem Vector.</p>
<p>Das verstehe ich soweit. Nur kommt nun meine Frage:</p>
<p>Wie rufe ich das ganze auf?<br />
Ich habe leider keine Erfahrung mit Iteratoren und Container.</p>
<p>Die Klassen habe ich als Beispiel um das erweitert, aber wie rufe ich diese ostream Funktion auf.</p>
<pre><code>friend ostream&amp; operator&lt;&lt;( ostream&amp; f, const XYZ&amp; x )
</code></pre>
<p>Dachte eigentlich das ich sowas mache:</p>
<pre><code class="language-cpp">void XYZ::speichern(void)
{
 fstream in_out(&quot;Test.dat&quot;, ios_base::in | ios_base::out);

 // Daten hineingeben
           //&lt;&lt;--------Hier sollte irgendwie dieses ostream&amp; rein, aber ich bekomme den nicht aufgerufen.

 // Datei schließen
 in_out.close();
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1477045</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1477045</guid><dc:creator><![CDATA[egcactus]]></dc:creator><pubDate>Wed, 19 Mar 2008 08:13:30 GMT</pubDate></item><item><title><![CDATA[Reply to Muss ich Vectoren serialisieren oder geht das auch irgendwie einfacher? on Wed, 19 Mar 2008 08:44:22 GMT]]></title><description><![CDATA[<p>egcactus schrieb:</p>
<blockquote>
<p><strong>const_iterator</strong> bedeutet wohl, dass er stets den konstanten Abstand von int einhalten soll.</p>
</blockquote>
<p>Ein <code>const_iterator</code> ist ein Iterator, der auf konstante Daten verweist.</p>
<p>egcactus schrieb:</p>
<blockquote>
<p>Wie rufe ich das ganze auf?<br />
Ich habe leider keine Erfahrung mit Iteratoren und Container.</p>
</blockquote>
<p>Der ganze Spaß ist eine Überladung der <code>&lt;&lt;</code> und <code>&gt;&gt;</code> Operatoren für <code>std::ostream</code> und <code>std::istream</code> damit kannst Du die Daten &quot;direkt&quot; in und aus dem Stream schieben:</p>
<pre><code class="language-cpp">XYZ xyz;
std::fstream in_out(&quot;Test.dat&quot;, ios_base::in | ios_base::out);

in_out &lt;&lt; xyz;
in_out &gt;&gt; xyz;
</code></pre>
<p>Badestrand schrieb:</p>
<blockquote>
<p>Ohne Gewähr und Implementationsabhängig <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>
</blockquote>
<p>Was ist daran Implementationsabhängig?</p>
<p>greetz, Swordfish</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1477060</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1477060</guid><dc:creator><![CDATA[Swordfish]]></dc:creator><pubDate>Wed, 19 Mar 2008 08:44:22 GMT</pubDate></item><item><title><![CDATA[Reply to Muss ich Vectoren serialisieren oder geht das auch irgendwie einfacher? on Wed, 19 Mar 2008 11:54:53 GMT]]></title><description><![CDATA[<p>Swordfish schrieb:</p>
<blockquote>
<p>Was ist daran Implementationsabhängig?</p>
</blockquote>
<p>Ich weiß nicht, ob der Typ von <code>vector&lt;T&gt;::size_type</code> vorgeschrieben ist, weil wenn nicht, kann dieser Typ je nach Implementierung verschieden groß sein. Dann schreibt man mit dem von Compiler x erstellten Programm einen 8-Byte-int als Größe in die Binärdatei und liest einen 4-Byte-int mit einem von Compiler y erstellten Programm wieder aus. So in etwa und falls dem so sein sollte und so <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>edit: Ach, und die Größe von normalen ints ist ja schon nicht festgelegt. Aber man könnte das ja umgehen, indem man fixe Größen rausschreibt, muss man halt nur entsprechend casten.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1477167</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1477167</guid><dc:creator><![CDATA[Badestrand]]></dc:creator><pubDate>Wed, 19 Mar 2008 11:54:53 GMT</pubDate></item><item><title><![CDATA[Reply to Muss ich Vectoren serialisieren oder geht das auch irgendwie einfacher? on Wed, 19 Mar 2008 18:00:13 GMT]]></title><description><![CDATA[<p>Ich mache irgend etwas falsch. Bei mir legt er nicht mal eine Datei an.</p>
<p>Damit ich den Ablauf verstehe, habe ich mir ein Beispielprojekt angelegt. Das aus den Formularen besteht: Klassen.cpp / Klassen.h, Daten.cpp / Daten.h und Grundbild.cpp / Grundbild.hDas sieht nun so aus:</p>
<p>Klassen.h</p>
<pre><code class="language-cpp">class VectorDaten
{
 private:

 public:
    VectorDaten(){}
    ~VectorDaten(){}

    // Variablen
    double                  a;
    vector&lt;int&gt;             b;
    vector&lt; vector&lt;float&gt; &gt; c;
    vector&lt;float&gt;           d;

    friend std::ostream&amp; operator&lt;&lt;(std::ostream&amp; f, const VectorDaten&amp; x );
    friend std::istream&amp; operator&gt;&gt;(std::istream&amp; f, VectorDaten&amp; x );

};

class TE       // Testklasse mit enthaltenen VectorDaten Klasse
{
 private:

 public:
    TE(){}
    ~TE(){}

    class VectorDaten Daten;

    // Funktion zum Speichern
    void sichern(void);
    void laden(void);

    friend std::ostream&amp; operator&lt;&lt;(std::ostream&amp; f, const VectorDaten&amp; x );
    friend std::istream&amp; operator&gt;&gt;(std::istream&amp; f, VectorDaten&amp; x );

};
</code></pre>
<p>Klassen.cpp</p>
<pre><code class="language-cpp">// Externe Daten einbinden
extern class VectorDaten Haus;
extern class TE Test;

// Sichern Funktion
void TE::sichern(void)
{
 // Einrichten eines Ein / Ausgabe Pfades
 std::fstream in_out(&quot;C:\\Test.dat&quot;, ios_base::in | ios_base::out);

 // Daten hineingeben
 in_out &lt;&lt;  Test.Daten;

 // Dateiverbindung schließen
 in_out.close();
}

// Laden Funktion
void TE::laden(void)
{
 // Einrichten eines Ein / Ausgabe Pfades
 std::fstream in_out(&quot;C:\\Test.dat&quot;, ios_base::in | ios_base::out);

 // Daten hineingeben
 in_out &gt;&gt;  Test.Daten;

 // Dateiverbindung schließen
 in_out.close();
}
</code></pre>
<p>und im Grundbild habe ich folgendes:</p>
<pre><code class="language-cpp">extern class VectorDaten Haus;
extern class TE Test;

TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
 // Datensatz
 Haus.b.push_back(1);
 Haus.b.push_back(2);
 Haus.b.push_back(3);

 Haus.d.push_back(2.5);
 Haus.d.push_back(3.5);

 Haus.c.push_back(Haus.d);

 // Datensatz in Klasse
 Test.Daten.b.push_back(100);
 Test.Daten.b.push_back(200);
 Test.Daten.b.push_back(300);

 Test.Daten.d.push_back(22.55);
 Test.Daten.d.push_back(33.55);

 Test.Daten.c.push_back(Haus.d);

}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
 Test.sichern();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
 Test.laden();
}
//---------------------------------------------------------------------------
</code></pre>
<p>Speichern wird durchlaufen, es wird aber keine Datei angelegt, beim Laden bleibt bei er <strong>in_out &gt;&gt; Test.Daten</strong> hängen.</p>
<p>Vermutlich, weil er ja auch keine Datei anlegt.</p>
<p>Was mache ich falsch?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1477447</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1477447</guid><dc:creator><![CDATA[egcactus]]></dc:creator><pubDate>Wed, 19 Mar 2008 18:00:13 GMT</pubDate></item><item><title><![CDATA[Reply to Muss ich Vectoren serialisieren oder geht das auch irgendwie einfacher? on Thu, 20 Mar 2008 06:21:25 GMT]]></title><description><![CDATA[<p>Ich habe meinen Fehler gefunden</p>
<pre><code>std::fstream in_out(&quot;C:\\Test.dat&quot;, ios_base::in | ios_base::out);
</code></pre>
<p>Sollte einfach die Datei nicht zum Lesen und Schreiben gleichzeitig öffnen.</p>
<pre><code>std::fstream in_out(&quot;C:\\Test.dat&quot;, ios_base::out);
</code></pre>
<p>Vielen Herzlichen Dank für eure Hilfe.<br />
Werde das ganze mal in mein Projekt einpflegen.</p>
<p>Überglücklich dass, das funktioniert <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
<p>Viele Grüße<br />
egcactus</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1477599</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1477599</guid><dc:creator><![CDATA[egcactus]]></dc:creator><pubDate>Thu, 20 Mar 2008 06:21:25 GMT</pubDate></item><item><title><![CDATA[Reply to Muss ich Vectoren serialisieren oder geht das auch irgendwie einfacher? on Fri, 21 Mar 2008 05:19:21 GMT]]></title><description><![CDATA[<p>Eine Frage ist jetzt noch aufgetreten:</p>
<p>Ich habe eine Klasse CUOFreq mit einem Public Teil aus der Klasse CFreq. Wenn ich mein Speichern aufrufe, dann arbeitet er wunderbar den ostream von CUOFreq ab. Aber den Teil der Variablen die in CFreq stehen, werden nicht berücksichtigt. Kann ich die ostream Funktion in CUOFreq irgendwie erweitern, dass er zuerst die ostream Funktion aus CFreq abarbeitet und anschließend CUOFreq.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1478167</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1478167</guid><dc:creator><![CDATA[egcactus]]></dc:creator><pubDate>Fri, 21 Mar 2008 05:19:21 GMT</pubDate></item><item><title><![CDATA[Reply to Muss ich Vectoren serialisieren oder geht das auch irgendwie einfacher? on Fri, 21 Mar 2008 08:12:14 GMT]]></title><description><![CDATA[<p>ich hab mir jetzt mal deine letzten Codeschnipsel angesehen, und ich glaub ich weis, wo dein Problem ist ;). du hast den operator&lt;&lt; bzw operator&gt;&gt; noch nicht ganz verstanden. Zumindest nicht so, wie er hier vorgeschlagne wurde.</p>
<p>In der Stream Bibliothek von C++ hat man sich dazu entschlossen, das Speichern von Objekten mit einer uniformen Technik zu regeln, den stream operatoren. Dies ist natürlich keine Pflicht, aber man sollte es der übersichtlichkeithalber so machen.</p>
<p>Die Idee dahinter ist, dass man jedes Objekt gleich speichern kann.</p>
<pre><code class="language-cpp">//Foo ist irgendein beliebiger typ.
class Foo foo;
cout&lt;&lt;foo;
</code></pre>
<p>das Objekt foo wird hierbei auf der Console ausgegeben. Natürlich kann man cout auch durch beliebige andere Stream Objekte austauschen.</p>
<p>Damit das funktioniert, muss jedes Objekt das gespeichert werden soll einen stream operator anbieten.</p>
<p>Nehmen wir zum Beispiel mal folgende einfache Struktur:</p>
<pre><code class="language-cpp">struct Foo
{
    int x,y,z;
};

//stream operator dazu
ostream&amp; operator&lt;&lt;(ostream&amp; str,const Foo&amp; foo)
{
    str&lt;&lt;foo.x&lt;&lt;foo.y&lt;&lt;foo.z;
    return str;
}

//Anwendungsbeispiel:
Foo foo1,foo2,foo3;
//...
cout&lt;&lt;foo1&lt;&lt;foo2&lt;&lt;foo3;

//gleiches natürlich auch für operator&gt;&gt; spar ich mir aber erstmal.
</code></pre>
<p>Wenn jetzt Foo Member eines anderen Objektes ist, möchte man Foo natürlich auch ausgeben können. Auch das ist nun sehr einfach:</p>
<pre><code class="language-cpp">class Bar
{
    private:
        Foo foo;
        Baz baz;
        int i;
        friend ostream&amp; operator&lt;&lt;(ostream&amp;,const Bar&amp;);
    public:
        //...
};
ostream&amp; operator&lt;&lt;(ostream&amp; str,const Bar&amp; bar)
{
    str&lt;&lt;bar.foo&lt;&lt;bar.baz&lt;&lt;bar.i;
    return str;
}
</code></pre>
<p>Nun sollte auch klar sein, wie man die Stream operatoren verwendet, ich veränder dazu mal deinen Codeschnipsel:</p>
<pre><code class="language-cpp">//Klassen.h
//Vectordaten ist korrekt, also überspringen

//...

//Klasse TE
//vorwärtsdeklarationen nicht vergessen, spar ich mir aber

class TE       // Testklasse mit enthaltenen VectorDaten Klasse
{
 private:
      VectorDaten daten;//interne Daten gehören nach private!
 public:
    TE(){}
    ~TE(){}

    // Funktion zum Speichern entfernt, da unnötig!

    //friend declaration geändert,alte war unnötig!
    //const correctness beachten!
    friend std::ostream&amp; operator&lt;&lt;(std::ostream&amp;,const TE&amp;);
    friend std::istream&amp; operator&gt;&gt;(std::istream&amp;,const VectorDaten&amp;);

};
</code></pre>
<pre><code class="language-cpp">//Klassen.cpp

//...

std::ostream&amp; operator&lt;&lt;(std::ostream&amp; str,const TE&amp; o)
{
    str&lt;&lt;o.daten;
    return str;
}
std::istream&amp; operator&gt;&gt;(std::istream&amp; str,const VectorDaten&amp; o)
{
    //leer zwecks übungszwecken
}
//...
</code></pre>
<p>und dann noch:</p>
<pre><code class="language-cpp">//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
    std::ofstream out(&quot;C:\\Test.dat&quot;);
    out&lt;&lt;Test;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
 //leer zwecks übungszwecken
}
//---------------------------------------------------------------------------
</code></pre>
<p>Jetzt solltest du deine Daten bequm speichern können.</p>
<p>Aber wichtig: interne daten niemals public.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1478176</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1478176</guid><dc:creator><![CDATA[otze]]></dc:creator><pubDate>Fri, 21 Mar 2008 08:12:14 GMT</pubDate></item><item><title><![CDATA[Reply to Muss ich Vectoren serialisieren oder geht das auch irgendwie einfacher? on Fri, 21 Mar 2008 15:07:11 GMT]]></title><description><![CDATA[<p>Hallo otze,</p>
<p>danke für deine Erklärung. Ich hatte das in meinem Projekt so schon umgesetzt es war nur noch ein Fehler in meinem Testprogramm.</p>
<p>Was ich meinte war: Das ich eine Klasse die bereits eine ostream Funktion hat an eine andere Klasse vererbe. Die erbende Klasse hat auch eine ostream Funktion.</p>
<p>Wenn ich nun in der erbenden Klasse die ostream Funktion programmieren möchte, dann habe ich keinen Zugriff auf die geerbte Klasse.</p>
<p>Hier das Beispiel:</p>
<pre><code class="language-cpp">class CFreq
{
 private: 
    int Anzahl;
    float Frequenz_Minimum;

 public:
  CFreq(){};
  ~CFreq(){};

 friend std::ostream&amp; operator&lt;&lt;(std::ostream&amp; f,const CFreq&amp; Daten);
 friend std::istream&amp; operator&gt;&gt;(std::istream&amp; f,const CFreq&amp; Daten);
};
</code></pre>
<pre><code class="language-cpp">class CUOFreq : public CFreq
{
 private: 
    float Messschritt;
    float Frequenz_Maximum;

 public:
  CUOFreq(){};
  ~CUOFreq(){};

 friend std::ostream&amp; operator&lt;&lt;(std::ostream&amp; f,const CUOFreq&amp; Daten);
 friend std::istream&amp; operator&gt;&gt;(std::istream&amp; f,const CUOFreq&amp; Daten);
};
</code></pre>
<p>Dadurch das ich die Klasse CFreq an CUOFreq vererbe habe ich nur Zugriff auf die Public Funktionen.</p>
<p>Wenn ich nun im ostream, der Klasse CUOFreq angebe</p>
<pre><code>f &lt;&lt; Daten.Messschritt &lt;&lt; Daten.Frequenz_Maximum;
</code></pre>
<p>Werden mir die Daten gespeichert. Ich kann aber nicht angeben</p>
<pre><code>f &lt;&lt; Daten.Anzahl &lt;&lt; Daten.Frequenz_Minimum;
</code></pre>
<p>Weil er darauf keinen Zugriff hat. Wenn ich aber die Klasse erzeuge, dann erzeuge ich ja.</p>
<pre><code class="language-cpp">CUOFreq Bauteil;
</code></pre>
<p>Da ich im Bauteil ja über die öffentlichen Schnittstellen zugriff auf CFreq habe ist das soweit ok. Nur beim Speichern hat er keinen Zugriff auf den ostream von CFreq und so werden nur float Messschritt; float Frequenz_Maximum gespeichert und die Anzahl und die Frequenz_Minimum stehen nicht in der Datei.</p>
<p>Meine Frage ist nun, wie kann ich in CUOFreq einen Zugriff auf den ostream von CFreq bekommen. Also auf den ostream der geerbten Klasse.</p>
<p>Grüße<br />
egcactus</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1478271</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1478271</guid><dc:creator><![CDATA[egcactus]]></dc:creator><pubDate>Fri, 21 Mar 2008 15:07:11 GMT</pubDate></item><item><title><![CDATA[Reply to Muss ich Vectoren serialisieren oder geht das auch irgendwie einfacher? on Sat, 22 Mar 2008 10:55:48 GMT]]></title><description><![CDATA[<blockquote>
<p>Meine Frage ist nun, wie kann ich in CUOFreq einen Zugriff auf den ostream von CFreq bekommen. Also auf den ostream der geerbten Klasse.</p>
</blockquote>
<p>Also da gibt es erstmal mehrere möglichkeiten, aber du hast zuersteinmal ein anderes Problem.</p>
<pre><code class="language-cpp">void print1(CuoFreq&amp; freq)
{
    cout&lt;&lt;freq;
}
void print2(CFreq&amp; freq)
{
    cout&lt;&lt;freq;
}
CuoFreq test;
print1(test);
print2(test);
</code></pre>
<p>selbst wenn deine Operatoren ordentlich funktionieren würden, bekämst du 2 unterschiedliche ergebnisse. der erste Fall nutzt den operator&lt;&lt; von CuoFreq der zweite den von Freq, und die haben bei dir unterschiedliches verhalten. Sowas will niemand, vorallem nicht in einem polymorphen zusammenhang.</p>
<p>Also korrigieren wir erstmal das:</p>
<pre><code class="language-cpp">class CFreq
{
 private:
    int Anzahl;
    float Frequenz_Minimum;

 protected:
     virtual void serialize(ostream&amp; stream)const;

 public:
  CFreq(){};
  ~CFreq(){};

 friend std::ostream&amp; operator&lt;&lt;(std::ostream&amp; f,const CFreq&amp; Daten);
 friend std::istream&amp; operator&gt;&gt;(std::istream&amp; f,const CFreq&amp; Daten);
}; 

//in der cpp datei
std::ostream&amp; operator&lt;&lt;(std::ostream&amp; f,const CFreq&amp; Daten)
{
     Daten.serialize(f);
}
void CFreq::serialize(ostream&amp; f)
{
    f&lt;&lt;Anzahl&lt;&lt;Frequenz_Minimum;
}
</code></pre>
<p>Washabe ich hier gemacht? ich hab deinen operator&lt;&lt; so verändert, dass er nun auf die virtuelle Funktion serialize verweist. Dadurch ist es dir erstmal möglich, dass du zumindest das verhalten anpassen kannst.</p>
<p>Nun zu deinem ursprünglichen Problem:<br />
Nun, die Lösung ist durch die letzte Änderung auch sehr einfach. Wir müssen nur explizit auf die Basisklassenversion von serialize zugreifen.</p>
<pre><code class="language-cpp">class CUOFreq : public CFreq
{
 private:
    float Messschritt;
    float Frequenz_Maximum;

 public:
  CUOFreq(){};
  ~CUOFreq(){};
}; 

//in der cpp
void CUOFreq::serialize(ostream&amp; f)
{
    //aufrufen der serialize funktion von CFreq
    CFreq::serialize(f);
    //ausgeben der neuen Daten.
    f&lt;&lt;Messschritt&lt;&lt;Frequenz_Maximum;
}
</code></pre>
<p>Allgemein musst du natürlich bei vererbung auch der abgeleiteten Klasse ein Interface geben, um die benötigten Daten zu bekommen. Du kannst zb eine protected get-funktion nutzen, die den wert der variablen zurück gibt. (falls dir das konzept der get und set funktionen unklar ist, da du ja auch die internen daten zuerst public gesetzt hattest in deinem startpost: eine getFunktion ist nur eine funktion die den internen wert zurückgibt, also nur ein &quot;return variable;&quot; beinhaltet. Set funktionen sind funktionen die den neuen variablenwert als argument entgegennehmen und ihn zuweisen.). Das ist sehr sicher, da du damit auch gleich unterbunden hast, dass die abgeleitete Klasse in den Daten der basisklasse rumpfuschen kann.</p>
<p>ps: du solltest statt &quot;zugriff auf den ostream der geerbten Klasse&quot; lieber &quot;zugriff auf die Ausgabefunktion (bzw operator&lt;&lt;) der geerbten Klasse&quot; schreiben. Der ostream ist ein eigenes Objekt, dass keiner der beiden Klassen gehört <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/1478621</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1478621</guid><dc:creator><![CDATA[otze]]></dc:creator><pubDate>Sat, 22 Mar 2008 10:55:48 GMT</pubDate></item><item><title><![CDATA[Reply to Muss ich Vectoren serialisieren oder geht das auch irgendwie einfacher? on Sun, 23 Mar 2008 10:07:59 GMT]]></title><description><![CDATA[<p>Mit den get und set Funktionen meinst du einfach Funktionen mit denen ich einen Wert hinein bzw. heraushole in dieser Art:</p>
<pre><code class="language-cpp">int getAnzahl(void)
{
 return Anzahl;
}
</code></pre>
<p>Ich habe meine Vectoren immer noch im public Teil untergebracht, da ich eigentlich die Funktionalität der Vectoren nutzen wollte in dem ich einfach die PushBack Funktion ausführe.</p>
<p>Bsp:</p>
<pre><code>Te.Daten.push_back(int);
</code></pre>
<p>Sobald sie private sind, muß ich dafür gleich einige Funktionen schreiben, die das umkopieren, rausholen, sortieren...</p>
<p>Ich habe in der Zwischenzeit, bis du mir das virtual gezeigt hast, auch etwas anderes ausprobiert.</p>
<p>In den Klassen habe ich folgende Funktionen angelegt:</p>
<pre><code class="language-cpp">// Daten speichern
         void speichern(ostream&amp; out);

         // Daten laden
         void laden(istream&amp; in);
</code></pre>
<p>Und in der cpp</p>
<pre><code class="language-cpp">void C1UOFreq::speichern(ostream&amp; out)
{
 // Daten an Ostream übergeben
 Eigenschaft.speichern(out);
 Freq.speichern(out);
 Container[0].speichern(out);
}

void C1UOFreq::laden(istream&amp; in)
{
 // Daten an Ostream übergeben
 Eigenschaft.laden(in);
 Freq.laden(in);
 Container[0].laden(in);
}
//---------------------------------------------------------------------------
</code></pre>
<p>So übergebe ich den ostream, bzw. den istream in die jeweilige Klasse und jede Klasse setzt dann einfach ihre Daten in den Stream bzw. holt sie sich.</p>
<pre><code class="language-cpp">void CElement::speichern(ostream&amp; out)
{
 // Daten an Ostream übergeben
 out &lt;&lt; name &lt;&lt; &quot; &quot; &lt;&lt; masseinheit &lt;&lt; &quot; &quot; &lt;&lt; pegelmasseinheit &lt;&lt; endl;
}
</code></pre>
<p>Weiß jetzt nicht ob das eine saubere Lösung ist. Deine sieht eleganter aus. Aber ich bin froh, dass ich das hinbekommen habe, bis du mir den Tip mit virtual gegeben hast.</p>
<p>Wir hatten 3 Jahre lang C Unterricht und das höchste der Gefühle waren Strukturen. Im Vergleich zu dem was ich hier in diesem Forum in einem halben Jahr gelernt habe war das in der Schule Kinderkram.</p>
<p>Danke nochmal für eure Hilfe.</p>
<p>Viele Grüße und Frohe Ostern<br />
egcactus</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1479038</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1479038</guid><dc:creator><![CDATA[egcactus]]></dc:creator><pubDate>Sun, 23 Mar 2008 10:07:59 GMT</pubDate></item></channel></rss>