<?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[persistentes double-Array]]></title><description><![CDATA[<p>Hi,<br />
ich sitze gerade an einer Aufgabe und komme überhaupt nicht weiter...<br />
Ich soll ein persistentes double-Array als Klasse realisieren,<br />
es sollen dann Zugriffe und Zuweisungen wie:</p>
<p>feld1[0] = 17.0;<br />
feld1[2] = 5 * feld1[0] * feld[1]+3.0;</p>
<p>möglich sein.</p>
<p>Die double-Daten sollen binär nacheinander in einer Datei liegen, der dateiname wird vom konstruktor eingelesen</p>
<p>Dazu muss ich die Operatoren [] und = passend überladen, mit den Befehlen read, write, e.t.c.</p>
<p>ich habe schon einiges probiert, aber bin mir zum beispiel nicht sicher über die Rückgabewerte der Operatoren...</p>
<p>alles etwas wirr, vielleicht hat hier jemand ja schon sowas gemacht, hier noch etwas code:</p>
<pre><code>[cpp]
class persFeld {

private:
	int n;
	double zahl;
	int index;
	fstream ausgabe;
public:
		persFeld(string Datei);
	void setzElement(int i,double x);
	void erweiterFeld(int i);
	persFeld operator[](int i);
	void operator=(double x);
};

persFeld persFeld::operator[](int i){
	ausgabe.seekg(0);
	ausgabe.read((char*)&amp;zahl,sizeof(double));
	cout &lt;&lt; &quot;index: &quot; &lt;&lt; i;
	index=i; 
}

void persFeld::operator=(double x){
	setzElement(index,x);
}

persFeld::persFeld(string Dateiname){
	fstream hilf(Dateiname.c_str(),ios::out|ios::app); 
	hilf.close();
 	ausgabe.open(Dateiname.c_str(),ios::out|ios::in);
	n=0;

}

void persFeld::setzElement(int i, double x){
	ausgabe.seekp(i*8);
	ausgabe.write((char*)&amp;x,sizeof(double));
}
[/cpp]
</code></pre>
<p>Vielleicht kennt sich hier ja jemand super aus mit Operatorenüberladung und Dateioperationen, damit die zuweisungen von oben klappen...</p>
<p>Danke!! <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/topic/211646/persistentes-double-array</link><generator>RSS for Node</generator><lastBuildDate>Wed, 14 Oct 2026 11:24:13 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/211646.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 25 Apr 2008 14:47:41 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to persistentes double-Array on Mon, 28 Apr 2008 15:48:27 GMT]]></title><description><![CDATA[<p>Hi,<br />
ich sitze gerade an einer Aufgabe und komme überhaupt nicht weiter...<br />
Ich soll ein persistentes double-Array als Klasse realisieren,<br />
es sollen dann Zugriffe und Zuweisungen wie:</p>
<p>feld1[0] = 17.0;<br />
feld1[2] = 5 * feld1[0] * feld[1]+3.0;</p>
<p>möglich sein.</p>
<p>Die double-Daten sollen binär nacheinander in einer Datei liegen, der dateiname wird vom konstruktor eingelesen</p>
<p>Dazu muss ich die Operatoren [] und = passend überladen, mit den Befehlen read, write, e.t.c.</p>
<p>ich habe schon einiges probiert, aber bin mir zum beispiel nicht sicher über die Rückgabewerte der Operatoren...</p>
<p>alles etwas wirr, vielleicht hat hier jemand ja schon sowas gemacht, hier noch etwas code:</p>
<pre><code>[cpp]
class persFeld {

private:
	int n;
	double zahl;
	int index;
	fstream ausgabe;
public:
		persFeld(string Datei);
	void setzElement(int i,double x);
	void erweiterFeld(int i);
	persFeld operator[](int i);
	void operator=(double x);
};

persFeld persFeld::operator[](int i){
	ausgabe.seekg(0);
	ausgabe.read((char*)&amp;zahl,sizeof(double));
	cout &lt;&lt; &quot;index: &quot; &lt;&lt; i;
	index=i; 
}

void persFeld::operator=(double x){
	setzElement(index,x);
}

persFeld::persFeld(string Dateiname){
	fstream hilf(Dateiname.c_str(),ios::out|ios::app); 
	hilf.close();
 	ausgabe.open(Dateiname.c_str(),ios::out|ios::in);
	n=0;

}

void persFeld::setzElement(int i, double x){
	ausgabe.seekp(i*8);
	ausgabe.write((char*)&amp;x,sizeof(double));
}
[/cpp]
</code></pre>
<p>Vielleicht kennt sich hier ja jemand super aus mit Operatorenüberladung und Dateioperationen, damit die zuweisungen von oben klappen...</p>
<p>Danke!! <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/1498130</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1498130</guid><dc:creator><![CDATA[fastpath]]></dc:creator><pubDate>Mon, 28 Apr 2008 15:48:27 GMT</pubDate></item><item><title><![CDATA[Reply to persistentes double-Array on Fri, 25 Apr 2008 17:52:11 GMT]]></title><description><![CDATA[<p>Das sieht ja alles ziemlich wirr bei deinem Code aus.</p>
<p>Zum einen mußt du beim operator [] unterscheiden, ob du lesend oder schreibend darauf zugreifst.</p>
<pre><code class="language-cpp">// lesen, daher konstant
double operator[](int i) const;

// schreiben
Proxy operator[](int i);
</code></pre>
<p>Du solltest als Rückgabewert für den nicht-konstanten Operator eine sogenannte Proxy-Klasse erzeugen, welche nur dazu dient, den operator = anzubieten.<br />
(Verwende möglichst nicht die selbe Klasse dafür, das ergibt nur ein unnötiges Durcheinander...)<br />
Versuche ersteinmal den lesenden Zugriff hinzukriegen und danach fängst du dann mit der Proxyklasse an. Ich hoffe, du weiß schon was Referenzen sind (und wie man diese sinnvoll einsetzt), denn für den Konstruktor der Proxy-Klasse benötigst du diese...</p>
<p>Und zum anderen mußt du den Zugriff auf die Datei auch einheitlich gestalten bzgl. seekg(i * sizeof(double)) ...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1498216</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1498216</guid><dc:creator><![CDATA[Th69]]></dc:creator><pubDate>Fri, 25 Apr 2008 17:52:11 GMT</pubDate></item><item><title><![CDATA[Reply to persistentes double-Array on Fri, 25 Apr 2008 18:13:07 GMT]]></title><description><![CDATA[<p>Hi,</p>
<p>also ich bin auch kein König dadrin, aber ich würde mal die erwarteten &quot;Semantiken&quot; durchgehen: Wie soll der Anwender die operatoren verwenden können ? Und was soll dabei passieren ?</p>
<p>Dann wird vielleicht klarer, wo welche Typen, wo Referenzen und wo Kopien erwartet werden.<br />
Z.B.:</p>
<pre><code class="language-cpp">// 1
arr[2] = arr[4] = 4.56;
// 2
double &amp;rd = arr[3];
rd += 1.23;
</code></pre>
<p>Außerdem mußt Du Dir ggf. überlegen, wann &quot;persistiert&quot; wird. So kannst Du sowas wie mit der double&amp; eigentlich nur &quot;im Speicher&quot; machen ... aber &quot;irgendwann&quot; muss das Zeug ja auch wieder in die Datei.</p>
<p>Gruß,</p>
<p>Simon2.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1498231</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1498231</guid><dc:creator><![CDATA[Simon2]]></dc:creator><pubDate>Fri, 25 Apr 2008 18:13:07 GMT</pubDate></item><item><title><![CDATA[Reply to persistentes double-Array on Sat, 26 Apr 2008 14:28:03 GMT]]></title><description><![CDATA[<p>Haben wir ein normales Array oder einen normalen Container, so erwarten wir als Ergebnis des []-Operators einen Verweis auf ein Objekt, dass mit dem entsprechenden Argument assoziert ist. Einen solcher Verweis können wir durch Referenzen realisieren. Haben wir es mit einer Kollektion aus Daten zu tun, die sich nicht im Speicher befinden, so müssen wir nach einem Ersatz für diese Referenz suchen, also ein Klassenobjekt, das auf das entsprechende Datum verweist bzw. dieses vertritt (daher der Name: proxy). Dieses Proxyobjekt muss dann derart gestaltet werden, dass es überall dort, wo wir eigentlich direkt unseren Datentyp (T=double) erwarten, eingesetzt werden kann. Das ist mit bestimmten Einschränkungen möglich.</p>
<pre><code class="language-cpp">class persFeld {
// ...
    class Proxy;
    Proxy operator[](int i);
// ...
};
</code></pre>
<p>Damit wir diesen Proxy dort einsetzen können, wo ein double erwartet wird, brauchen wir einen Konvertierungsoperator nach double. Zusätzlich soll die Zuweisung eines double möglich sein. Das realisieren wir mit einem entsprechenden Zuweisungsoperator. Schwierigkeiten ergeben sich dort, wo ein modifizierbares double-Objekt erwartet wird - im einfachsten Falle, wenn wir += -= *= usw. verwenden wollten. Diese Operatoren können wir geeignet überladen. Bei Funktionen, die einen entsprechenden Parameter erwarten, versagt diese Methode allerdings. Abhelfen könnte hier ein Konvertierungsoperator nach double&amp; - das Problem dabei ist, dass wir dann Schreibzugriffe nicht verfolgen können. Man könnte diese Schreibzugriffe im Destruktor auswerten, nur ändert sich dann die Semantik von Ausdrücken möglicherweise in unerwarteter Weise, weil Seiteneffekte erst bei Ende der Auswertung eines Ausdrucks (wenn der Destruktor des Proxies ausgeführt wird) auftreten und nicht an jedem Sequenzpunkt des Ausdrucks. Diese Möglichkeit soll hier nicht weiter verfolgt werden.<br />
Zusätzlich müssen wir uns Gedanken über die Kopiersemantik von Proxies machen. Da er als Rückgabewert einer Funktion (wenigstens des []-Operators) auftreten kann, brauchen wir einen Copy-ctor, der sich logisch normal verhält. Schwieriger ist die Copy-Zuweisung. Haben wir</p>
<pre><code class="language-cpp">persFeld a(..);
</code></pre>
<p>Dann soll bei</p>
<pre><code class="language-cpp">a[i]=a[j];
</code></pre>
<p>natürlich der Wert an der Stelle j in der Stelle i gespeichert werden, und nicht etwa der Proxy auf der linken Seite umgebogen werden, um auf die Stelle j zu zeigen. Wir haben also einen Fall, bei dem Copy-Zuweisung und Copy-ctor völlig verschiedene Dinge machen - das muss nicht überraschen: Referenzen selbst sind ja auch nicht zuweisbar. Und so wie Referenzen kann man Proxies nicht in Standardcontainern speichern. Und zum Schluss stellt sich noch die Frage nach const.<br />
Haben wir ein konstantes Feld, könnten wir versucht sein, beim Aufruf des []-Operators gleich den Wert auszulesen und ein double zurückzugeben. Das ist legitim, hat allerdings den unschönen Effekt, dass wir in diesem Fall nicht mehr zwischen dem Ort eines Datums (der durch ein Proxy repräsentiert wird) und dem Wert des Datums unterscheiden können. Haben wir einen normalen Container, kann es sinnvoll sein, Referenzen auf Elemente zu speichern und den Wert erst später zu ermitteln:</p>
<pre><code class="language-cpp">const vector&lt;double&gt;&amp; v=...;
const double&amp; x = v[ /* komplexer Ausdruck, den wir nicht ständig neu berechnen wollen */ ];
for ( /* ... */ )
{
   mach_was_mit_x(x);
   mach_was_mit_v(v); // der Inhalt von x ändert sich möglicherweise
}
</code></pre>
<p>Wollen wir etwas Derartiges mit unserem Feld machen, müssen wir den eigentlichen Lesevorgang entsprechend verzögern, also muss auch unser konstanter []-Operator einen Proxy zurückgeben. Man könnte versucht sein hierbei mit const Proxy zu spielen.</p>
<pre><code class="language-cpp">class persFeld {
// ...
    class Proxy {
// ...
        Proxy&amp; operator=(double); // nur verwendbar, wenn nicht const
        operator double() const; // immer möglich
    };
    Proxy operator[](int);
    const Proxy operator[](int) const;
// ...
};
</code></pre>
<p>Das ist allerdings gefährlich, denn nichts hindert uns daran, den vom []-Operator zurückgegeben Proxy einfach noch einmal zu kopieren, und dann mit dieser Kopie zu arbeiten und den Wert doch noch zu verändern. Wir brauchen also eine zweite Klasse, die nur lesend aif den Wert zugreifen kann und unser normaler Proxy ist in diese konvertierbar. Der Vergleich mit Referenzen zeigt wiederum, dass diese Überlegung sinnvoll ist: ein Referenz auf ein konstantes T ist auch nicht einfach die konstante Version einer Referenz auf T - Referenzen selbst sind niemals cv-qualifiziert. Das führt zu der Überlegung, dass die const-Qualifikation eines Proxy-Objekts im Grunde bedeutungslos ist: folglich müssen alle Memberfunktionen (auch der Zuweisungsoperator!) const sein - der Proxy selber wird ja sowieso nicht verändert. Zusammenfasst:</p>
<pre><code class="language-cpp">class persFeld {
// ...
    class Proxy;
    class ConstProxy;
    Proxy operator[](int);
    ConstProxy operator[](int) const;
// ...
};

class persFeld::Proxy {
    Proxy(persFeld&amp; f, int i) : feld_(f), index_(i) {}
public:
    // Copy-ctor vom Compiler
    Proxy&amp; operator=(const Proxy&amp; other) const { // const !!
        // um Duplizität zu vermeiden, gibt es nur eine Stelle, an der geschrieben wird (der andere Zuweisungsoperator)
        // und eine Stelle, an der gelesen wird (der Konvertierungsoperator des ConstProxies)
        // überall sonst benutzen wir diese Funktionen
        double v = other;
        return *this = v;
    }
    Proxy&amp; operator=(double) const; // hier den Schreibvorgang implementieren (oder eine entsprechende Funktion von persFeld aufrufen)
    operator double() const;
    // Nach Bedarf noch ein paar Operatoren überladen:
    template&lt;typename T&gt;
    Proxy&amp; operator+=(T rhs) const {
        double v = *this;
        return *this = ( v += rhs );
    }
    // usw.
private:
    persFeld&amp; feld_; // normalerweise bin ich gegen Referenzen an dieser Stelle, hier sind sie mal sinnvoll
    int index_;
    friend class persFeld;
    friend class ConstProxy; // für die Konvertierung
};

class persFeld::ConstProxy {
    ConstProxy(const persFeld&amp; f, int i) : feld_(f), index_(i) {}
public:
    ConstProxy(const Proxy&amp; p) : feld_(p.feld_), index_(p.index_) {}
    // Copy-ctor vom Compiler
    // nicht zuweisbar, da Copy-Zuweisung vom Compiler wegen Referenzmember nicht definiert werden kann
public:
    operator double() const; // hier Lesevorgang implementieren (oder eine entsprechende Funktion von persFeld aufrufen)
private:
    friend class persFeld;
    const persFeld&amp; feld_;
    int index_;
};
inline persFeld::Proxy::operator double() const {
    ConstProxy p( *this );
    return p;
}

inline persFeld::Proxy persFeld::operator[](int i) {
    return Proxy( *this, i );
}
inline persFeld::ConstProxy persFeld::operator[](int i) const {
    return ConstProxy( *this, i );
}
</code></pre>
<p>Da sich auch durch den Lesevorgang möglicherweise der innere Zustand des Feld-Objektes ändert, ist dies ein Fall, in dem mutable nützlich werden kann, um so mehr falls man das Ganze noch durch Caching aufwertet.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1498442</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1498442</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Sat, 26 Apr 2008 14:28:03 GMT</pubDate></item><item><title><![CDATA[Reply to persistentes double-Array on Sun, 27 Apr 2008 12:57:51 GMT]]></title><description><![CDATA[<p>Vielen Dank!!</p>
<p>echt gut, dass ihr sofort auf ne Proxy-Klasse gekommen seid!!<br />
jetzt werde ich mich mal dransetzen, das richtig zu verstehen ^^</p>
<p>auf jeden Fall danke auch camper, für die Mühe, jetzt kann ich mir das zusammenpuzzlen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f44d.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--thumbs_up"
      title=":+1:"
      alt="👍"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1498992</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1498992</guid><dc:creator><![CDATA[fastpath]]></dc:creator><pubDate>Sun, 27 Apr 2008 12:57:51 GMT</pubDate></item><item><title><![CDATA[Reply to persistentes double-Array on Sun, 27 Apr 2008 18:43:47 GMT]]></title><description><![CDATA[<p>Proxies werden auch in der Standardbibliothek verwendet: bei vector&lt;bool&gt; und bitset (und evtl. noch an anderen Stellen, die mir gerade nicht einfallen).<br />
Ein paar Sachen kann man noch verbessern. ConstProxy hängt von Proxy ab, aber Proxy nicht unbedingt von ConstProxy, diese Koppelung war ungünstig. Außerdem habe ich die Klassen STL-mäßig umbenannt - man kann schließlich noch darüber nach denken, der Klasse ein Iteratorinterface zu spendieren. Auch der Zuweisungsoperator kann noch etwas smarter implementiert werden. Zudem war ich hinsichtlich des const etwas voreilig: zwar ist es logisch bedeutungslos, aber es sollte nicht unnötig dort hinzugefügt werden, wo es den Rückgabetypen beeinflussen würde, also braucht man non-const und const-Overloads.</p>
<pre><code class="language-cpp">class persFeld {
// ...
public:
    typedef int size_type;
private:    
    double read(size_type index) const;
    void write(size_type index, double value);
public:
    class reference {
        reference(persFeld&amp; f, size_type i) : feld_( f ), index_( i ) {}
    public:
        void operator=(volatile reference&amp;) volatile; // unterdrückt die Deklaration durch den Compiler, ist aber wegen seiner Signatur kein Kandidat bei der Überladungsauflösung
        reference&amp; operator=(double value)             { feld_.write( index_, value ); return *this; }
        const reference&amp; operator=(double value) const { feld_.write( index_, value ); return *this; }
        operator double() const { return feld_.read( index_ ); }
        template&lt;typename T&gt; reference&amp; operator+=(const T&amp; rhs) { return *this = *this + rhs; }
        template&lt;typename T&gt; reference&amp; operator-=(const T&amp; rhs) { return *this = *this - rhs; }
        template&lt;typename T&gt; reference&amp; operator*=(const T&amp; rhs) { return *this = *this * rhs; }
        template&lt;typename T&gt; reference&amp; operator/=(const T&amp; rhs) { return *this = *this / rhs; }
        template&lt;typename T&gt; const reference&amp; operator+=(const T&amp; rhs) const { return *this = *this + rhs; }
        template&lt;typename T&gt; const reference&amp; operator-=(const T&amp; rhs) const { return *this = *this - rhs; }
        template&lt;typename T&gt; const reference&amp; operator*=(const T&amp; rhs) const { return *this = *this * rhs; }
        template&lt;typename T&gt; const reference&amp; operator/=(const T&amp; rhs) const { return *this = *this / rhs; }

        friend size_type index(const reference&amp; p) { return p.index_; }
        friend persFeld&amp; feld(const reference&amp; p) { return p.feld_; }
    private:
        persFeld&amp; feld_;
        size_type index_;
        friend class persFeld;
    };
    class const_reference {
        const_reference(const persFeld&amp; f, size_type i) : feld_( f ), index_( i ) {}
    public:
        const_reference(const reference&amp; p) : feld_( feld( p ) ), index_( index( p ) ) {}
    private:
        void operator=(volatile const_reference&amp;) volatile; // nicht zuweisbar
    public:
        operator double() const { return feld_.read( index_ ); }

        friend size_type index(const const_reference&amp; p) { return p.index_; }
        friend const persFeld&amp; feld(const const_reference&amp; p) { return p.feld_; }
    private:
        const persFeld&amp; feld_;
        size_type index_;
        friend class persFeld;
    };

    reference operator[](size_type index) { return reference( *this, index ); }
    const_reference operator[](size_type index) const { return const_reference( *this, index ); }

    friend class reference;
    friend class const_reference;
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1499171</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1499171</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Sun, 27 Apr 2008 18:43:47 GMT</pubDate></item><item><title><![CDATA[Reply to persistentes double-Array on Mon, 28 Apr 2008 12:30:14 GMT]]></title><description><![CDATA[<p>Hallo fastpath,</p>
<p>das Problem klingt interessant, wenn Sie eine Lösung gefunden haben, bringen Sie sie bitte am Mittwoch zum Prakikum mit. Viel Glück</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1499624</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1499624</guid><dc:creator><![CDATA[jBiermann]]></dc:creator><pubDate>Mon, 28 Apr 2008 12:30:14 GMT</pubDate></item></channel></rss>