<?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[Wie internen Zustand von Objekt auslagern?]]></title><description><![CDATA[<p>Ich hatte diese Frage schon einmal gestellt. Und ich glaube, dass es eventuell mehr in RudP gehört, da es ein allgemeines Problem ist. Das letzte mal ist es nicht besonders toll gelaufen, weil ich den Fehler gemacht habe, ein Beispiel zu liefern und die Problemlösungen auf dieses spezielle Beispiel abgehoben sind und leider nur versuchten, das Problem auf Grundlage dieses einen Beispiels zu transformieren, anstatt es zu lösen &quot;das kannst du dort ganz anders machen&quot;. Diesen Fehler mache ich jetzt nicht. hah!</p>
<p>Ich hänge da jetzt echt lange dran, aber erst mal eine Grafik.</p>
<p><a href="http://imageshack.us/photo/my-images/607/classesg.png/" rel="nofollow">http://imageshack.us/photo/my-images/607/classesg.png/</a></p>
<p>Ich habe 2 Objekttypen A und B. Die Abhängigkeit zwischen ihnen lässt sich mit folgender Funktion beschreiben:</p>
<pre><code class="language-cpp">Result myFunc(A&amp; a, B&amp; b,Arg&amp; some_arg){
     Result temp=a.foo(some_arg);
     temp=b.transform(temp);
     return a.bar(temp);
}
</code></pre>
<p>Hierbei wird in a.foo ein interner Zustand geschrieben, der nur von some_arg abhängt, insbesondere nicht vom vorherigen Zustand. Das Ergebnis von foo wird dann irgendwie transformiert und das Resultat an A.bar übergeben wo der zuvor geschriebene Zustand sowie die transformierte Eingabe verwendet werden, das Endergebnis zu berechnen.</p>
<p>Soweit, so Abstrakt. Nun hat der Ansatz zwei Probleme:<br />
1. auch wenn ich es gerne würde, dieses Design macht es unmöglich, myFunc zu parallelisieren und es gibt Objekte vom Typ A die gar nicht parallelisierbar sind. Die Berechnungen sind aber so aufwendig, dass ich mehrere CPUs verwenden muss, sonst werde ich nie fertig (wir reden hier von Monaten Rechenzeit).</p>
<p>2. Das Interface ist wackelig. in A.bar gibt es keinen Hinweis darauf, dass A.foo vorher aufgerufen werden muss. Wir haben das zwar dokumentiert, aber schon gemerkt, dass die Studenten, die mit dem Interface arbeiteten dies nicht so wirklich realisiert haben und sich über falsche Ergebnisse wunderten. Es gilt also, das Interface Studentensicher zu machen.</p>
<p>Für mögliche Problemlösungen gibt es zwei weitere Probleme:<br />
1. es kann sein, dass alle Funktionen von A unglaublich schnell berechenbar sind und nur die schiere Masse der Funktionsaufrufe von myFunc das Problem schwer machen. Mögliche Lösungen müssen daher möglichst overheadfrei sein.<br />
2. A ist nicht kopierbar (A ist Basisklasse und das Interface erlaubt leider kein clone :()</p>
<p>Nun zu meinem Lösungsansatz:<br />
Ich habe versucht, den Zustand einfach aus der Klasse zu ziehen und als externes Objekt zu modellieren. Als Zustandstyp habe ich den schlechtmöglichsten Typ gewählt: std::vector&lt;double&gt;. Das Ding habe ich etwas weiter aufgebohrt zu einem &quot;State&quot;-Typ der subrange-operationen anbietet. das war notwendig für den Fall, dass A aus mehreren Objekten besteht, die jeweils ihren eigenen State haben.</p>
<p>Das Interface sieht nun so aus</p>
<pre><code class="language-cpp">struct A{
    virtual std::size_t stateSize(some_arg);
    virtual Result foo(some_arg, State&amp; state)=0;
    virtual Result bar(transformedFoo, State const&amp; state)=0;
};
</code></pre>
<p>und myfunc habe ich geändert zu:</p>
<pre><code class="language-cpp">Result myFunc(A&amp; a, B&amp; b,Arg&amp; some_arg){
     State state(a.stateSize(some_arg));
     Result temp=a.foo(some_arg,state);
     temp=b.transform(temp,state);
     return a.bar(temp);
}
</code></pre>
<p>pro:<br />
1. einfach<br />
2. meistens schnell<br />
3. funktioniert in 99% aller Fälle<br />
contra:<br />
1. unwartbarer code<br />
2. fehleranfällige Indexschieberei (in state befinden sich vektoren, matrizen, scalare... all das muss ich später aus dem Ding wieder raus popeln)<br />
3. funktioniert nicht immer</p>
<p>In der Tat ist es so schlimm, dass ich jetzt bei der Portierung eines Objektes einfach kapituliert habe, weil ich die Fehler nicht unter Kontrolle kriegen konnte.</p>
<p>Wenn ich in einer perfekten generischen Welt leben würde, würde ich das machen wollen:</p>
<pre><code class="language-cpp">struct A{
    struct State{...};//jeder Typ hat eigenen state
    Result foo(some_arg, State&amp; state)=0;
    Result bar(transformedFoo, State&amp; state)=0;
};
</code></pre>
<p>Aber ich lebe leider in einer unperfekten objektorientierten Welt, wo ich nur abstrakte Basisklassen haben kann.</p>
<p>Hat irgendjemand eine schnelle Lösung für mein Problem? Vielleicht auch einen anderen Ansatz? Ich bin für alles offen.</p>
<p>Danke fürs durchlesen <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="🙂"
    /> (ich bin auch nach Schreiben dieses Romans ratlos)</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/306934/wie-internen-zustand-von-objekt-auslagern</link><generator>RSS for Node</generator><lastBuildDate>Fri, 07 Aug 2026 04:39:15 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/306934.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 11 Aug 2012 06:11:57 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Wie internen Zustand von Objekt auslagern? on Sat, 11 Aug 2012 06:12:25 GMT]]></title><description><![CDATA[<p>Ich hatte diese Frage schon einmal gestellt. Und ich glaube, dass es eventuell mehr in RudP gehört, da es ein allgemeines Problem ist. Das letzte mal ist es nicht besonders toll gelaufen, weil ich den Fehler gemacht habe, ein Beispiel zu liefern und die Problemlösungen auf dieses spezielle Beispiel abgehoben sind und leider nur versuchten, das Problem auf Grundlage dieses einen Beispiels zu transformieren, anstatt es zu lösen &quot;das kannst du dort ganz anders machen&quot;. Diesen Fehler mache ich jetzt nicht. hah!</p>
<p>Ich hänge da jetzt echt lange dran, aber erst mal eine Grafik.</p>
<p><a href="http://imageshack.us/photo/my-images/607/classesg.png/" rel="nofollow">http://imageshack.us/photo/my-images/607/classesg.png/</a></p>
<p>Ich habe 2 Objekttypen A und B. Die Abhängigkeit zwischen ihnen lässt sich mit folgender Funktion beschreiben:</p>
<pre><code class="language-cpp">Result myFunc(A&amp; a, B&amp; b,Arg&amp; some_arg){
     Result temp=a.foo(some_arg);
     temp=b.transform(temp);
     return a.bar(temp);
}
</code></pre>
<p>Hierbei wird in a.foo ein interner Zustand geschrieben, der nur von some_arg abhängt, insbesondere nicht vom vorherigen Zustand. Das Ergebnis von foo wird dann irgendwie transformiert und das Resultat an A.bar übergeben wo der zuvor geschriebene Zustand sowie die transformierte Eingabe verwendet werden, das Endergebnis zu berechnen.</p>
<p>Soweit, so Abstrakt. Nun hat der Ansatz zwei Probleme:<br />
1. auch wenn ich es gerne würde, dieses Design macht es unmöglich, myFunc zu parallelisieren und es gibt Objekte vom Typ A die gar nicht parallelisierbar sind. Die Berechnungen sind aber so aufwendig, dass ich mehrere CPUs verwenden muss, sonst werde ich nie fertig (wir reden hier von Monaten Rechenzeit).</p>
<p>2. Das Interface ist wackelig. in A.bar gibt es keinen Hinweis darauf, dass A.foo vorher aufgerufen werden muss. Wir haben das zwar dokumentiert, aber schon gemerkt, dass die Studenten, die mit dem Interface arbeiteten dies nicht so wirklich realisiert haben und sich über falsche Ergebnisse wunderten. Es gilt also, das Interface Studentensicher zu machen.</p>
<p>Für mögliche Problemlösungen gibt es zwei weitere Probleme:<br />
1. es kann sein, dass alle Funktionen von A unglaublich schnell berechenbar sind und nur die schiere Masse der Funktionsaufrufe von myFunc das Problem schwer machen. Mögliche Lösungen müssen daher möglichst overheadfrei sein.<br />
2. A ist nicht kopierbar (A ist Basisklasse und das Interface erlaubt leider kein clone :()</p>
<p>Nun zu meinem Lösungsansatz:<br />
Ich habe versucht, den Zustand einfach aus der Klasse zu ziehen und als externes Objekt zu modellieren. Als Zustandstyp habe ich den schlechtmöglichsten Typ gewählt: std::vector&lt;double&gt;. Das Ding habe ich etwas weiter aufgebohrt zu einem &quot;State&quot;-Typ der subrange-operationen anbietet. das war notwendig für den Fall, dass A aus mehreren Objekten besteht, die jeweils ihren eigenen State haben.</p>
<p>Das Interface sieht nun so aus</p>
<pre><code class="language-cpp">struct A{
    virtual std::size_t stateSize(some_arg);
    virtual Result foo(some_arg, State&amp; state)=0;
    virtual Result bar(transformedFoo, State const&amp; state)=0;
};
</code></pre>
<p>und myfunc habe ich geändert zu:</p>
<pre><code class="language-cpp">Result myFunc(A&amp; a, B&amp; b,Arg&amp; some_arg){
     State state(a.stateSize(some_arg));
     Result temp=a.foo(some_arg,state);
     temp=b.transform(temp,state);
     return a.bar(temp);
}
</code></pre>
<p>pro:<br />
1. einfach<br />
2. meistens schnell<br />
3. funktioniert in 99% aller Fälle<br />
contra:<br />
1. unwartbarer code<br />
2. fehleranfällige Indexschieberei (in state befinden sich vektoren, matrizen, scalare... all das muss ich später aus dem Ding wieder raus popeln)<br />
3. funktioniert nicht immer</p>
<p>In der Tat ist es so schlimm, dass ich jetzt bei der Portierung eines Objektes einfach kapituliert habe, weil ich die Fehler nicht unter Kontrolle kriegen konnte.</p>
<p>Wenn ich in einer perfekten generischen Welt leben würde, würde ich das machen wollen:</p>
<pre><code class="language-cpp">struct A{
    struct State{...};//jeder Typ hat eigenen state
    Result foo(some_arg, State&amp; state)=0;
    Result bar(transformedFoo, State&amp; state)=0;
};
</code></pre>
<p>Aber ich lebe leider in einer unperfekten objektorientierten Welt, wo ich nur abstrakte Basisklassen haben kann.</p>
<p>Hat irgendjemand eine schnelle Lösung für mein Problem? Vielleicht auch einen anderen Ansatz? Ich bin für alles offen.</p>
<p>Danke fürs durchlesen <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="🙂"
    /> (ich bin auch nach Schreiben dieses Romans ratlos)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2240906</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2240906</guid><dc:creator><![CDATA[otze]]></dc:creator><pubDate>Sat, 11 Aug 2012 06:12:25 GMT</pubDate></item><item><title><![CDATA[Reply to Wie internen Zustand von Objekt auslagern? on Sat, 11 Aug 2012 07:53:48 GMT]]></title><description><![CDATA[<blockquote>
<p>Not every problem is an object, dude.</p>
</blockquote>
<p>Fuer Prallelisierung eignen sich in erster Linie zustandslose/freie Funktionen. Es scheint, dass du wenig Erfahrung damit hast.</p>
<blockquote>
<p>schnelle Lösung ... für alles offen</p>
</blockquote>
<p>Das widerspricht sich.</p>
<blockquote>
<p>Wenn ich in einer perfekten generischen Welt leben würde</p>
</blockquote>
<p>Machbar, beispielsweise durch Templates, type erasure oder pimpl.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2240913</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2240913</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Sat, 11 Aug 2012 07:53:48 GMT</pubDate></item><item><title><![CDATA[Reply to Wie internen Zustand von Objekt auslagern? on Sat, 11 Aug 2012 07:55:58 GMT]]></title><description><![CDATA[<p>Edit: Moment, da fehlt ein virtual. <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="😉"
    /><br />
Edit2: Okay</p>
<p>Was spricht dagegen?</p>
<pre><code class="language-cpp">class A
{
public:
  virtual Result baz(B&amp; b, Arg&amp; arg)
  {
    Zustand zustand;
    return bar(zustand, b.transform(foo(zustand, arg)));
  }

private:
  virtual Result foo(Zustand&amp; zustand, Arg&amp; arg); // static?
  virtual Result bar(const Zustand&amp; zustand, Result r); // static?
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2240920</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2240920</guid><dc:creator><![CDATA[cooky451]]></dc:creator><pubDate>Sat, 11 Aug 2012 07:55:58 GMT</pubDate></item><item><title><![CDATA[Reply to Wie internen Zustand von Objekt auslagern? on Sat, 11 Aug 2012 08:07:30 GMT]]></title><description><![CDATA[<p>knivil schrieb:</p>
<blockquote>
<blockquote>
<p>Not every problem is an object, dude.</p>
</blockquote>
<p>Fuer Prallelisierung eignen sich in erster Linie zustandslose/freie Funktionen.</p>
</blockquote>
<p>Was ja meinem Problem entspricht: wie kriege ich das Ding Zustandsfrei?. Das es diesen Zustand gibt, ist ein blödes Implementationsdetail, weil wir gerne effizienten Code haben wollen und deswegen nicht Ergebnisse großer Matrix-Matrix Multiplikationen weg werfen wollen. (oder im Falle von günstigen Funktionen ein Skalarprodukt oder das Ergebnis eines exp-Aufrufs).</p>
<blockquote>
<blockquote>
<p>schnelle Lösung ... für alles offen</p>
</blockquote>
<p>Das widerspricht sich.</p>
</blockquote>
<p>Nur, wenn man es drauf anlegt, dass es sich widerspricht. Ich bin erst mal für jede mögliche Lösung offen, würde dann aber Benchmarken, wie teuer sie ist.</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/11887">@cookie</a> Es gibt verschiedene Versionen von myFunc, die sich da in Kleinigkeiten unterscheiden. Die Aufteilung der Funktionen in dieser Art und Weise war ein iterativer Prozess über jetzt mehrere Jahre, und das ist die einzige Version, die alles kann, was wir brauchen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2240922</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2240922</guid><dc:creator><![CDATA[otze]]></dc:creator><pubDate>Sat, 11 Aug 2012 08:07:30 GMT</pubDate></item><item><title><![CDATA[Reply to Wie internen Zustand von Objekt auslagern? on Sat, 11 Aug 2012 07:55:29 GMT]]></title><description><![CDATA[<blockquote>
<p>Was spricht dagegen?</p>
</blockquote>
<p>Warum ueberhaupt eine Klasse?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2240923</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2240923</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Sat, 11 Aug 2012 07:55:29 GMT</pubDate></item><item><title><![CDATA[Reply to Wie internen Zustand von Objekt auslagern? on Sat, 11 Aug 2012 08:16:51 GMT]]></title><description><![CDATA[<p>das Ding hat Parameter, eine konfigurierbare Struktur und ist alles in allem recht kompex.</p>
<p>Es geht darum:<br />
<a href="http://image.diku.dk/shark/doxygen_pages/html/classshark_1_1_abstract_model.html#details" rel="nofollow">AbstractModel</a><br />
Das ist noch eine &quot;alte&quot; doku. Der Code an dem ich arbeite hat noch keine öffentlich zugängliche Dokumentation. Das ist also die Version ohne externen State und ich muss eval() und die (ersten) Ableitungen unter einen Hut kriegen.</p>
<p>Es wird alles komplizierter dadurch, dass ich durch die Form der Ableitungen in der Lage bin, die Modelle zu verketten und dann zum Beispiel Parameterableitungen für das gesamte Modell bilden kann.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2240929</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2240929</guid><dc:creator><![CDATA[otze]]></dc:creator><pubDate>Sat, 11 Aug 2012 08:16:51 GMT</pubDate></item><item><title><![CDATA[Reply to Wie internen Zustand von Objekt auslagern? on Sat, 11 Aug 2012 09:23:34 GMT]]></title><description><![CDATA[<p>otze schrieb:</p>
<blockquote>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/11887">@cookie</a> Es gibt verschiedene Versionen von myFunc, die sich da in Kleinigkeiten unterscheiden. Die Aufteilung der Funktionen in dieser Art und Weise war ein iterativer Prozess über jetzt mehrere Jahre, und das ist die einzige Version, die alles kann, was wir brauchen.</p>
</blockquote>
<p>Gibt es nun mehrere Versionen, oder nur eine? Und ist das so schwer zu ändern? Sieht für mich nach copy pasta aus. Wenn das nicht geht, sollte man das eventuell näher beschreiben, sonst macht es ja wenig Sinn Vorschläge zu machen, bei denen man garnicht weiß was geändert werden kann und was nicht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2240931</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2240931</guid><dc:creator><![CDATA[cooky451]]></dc:creator><pubDate>Sat, 11 Aug 2012 09:23:34 GMT</pubDate></item><item><title><![CDATA[Reply to Wie internen Zustand von Objekt auslagern? on Sat, 11 Aug 2012 16:57:01 GMT]]></title><description><![CDATA[<p>cooky451 schrieb:</p>
<blockquote>
<p>Gibt es nun mehrere Versionen, oder nur eine?<br />
Und ist das so schwer zu ändern? Sieht für mich nach copy pasta aus. Wenn das nicht geht, sollte man das eventuell näher beschreiben, sonst macht es ja wenig Sinn Vorschläge zu machen, bei denen man garnicht weiß was geändert werden kann und was nicht.</p>
</blockquote>
<p>wir haben bislang 4 verschiedene Versionen von myfunc, sowie 10 Modelle. Tendenz steigend. Wir müssen auch für die Zukunft etwas Luft nach oben haben, da sich die Bibliothek in einem Forschungsbereich befindet und rapid-prototyping möglich sein soll(also mal eben fix eine Idee ausprobieren und schauen, ob das funktioniert). Das Interface muss also flexibel sein und ich glaube, dass wir bereits jetzt die Flexibilität voll ausnutzen.</p>
<p>Deswegen glaube ich nicht, dass wesentliche Aspekte des Interfaces geändert werden können. Weitere Parameter oder neue Funktionen hinzuzufügen ist okay, da sich die Änderungen nicht weit fortpflanzen. Aber eine Änderung des grundlegenden Klassendesigns wird wohl eher nicht drin sein :(.</p>
<p>Oh und ich sitze alleine an der Implementation dieser Änderung ;).</p>
<p>//edit Es ist auch ein semantisches Problem. was myFunc im echten problem macht, ist eine Fehlerfunktion darstellen, das heißt messen wie gut das Modell A die gegebene Zielsetzung (zum Beispiel dargestellt durch <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f60e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--smiling_face_with_sunglasses"
      title="B)"
      alt="😎"
    /> erfüllt und einen Gradienten zu berechnen, der angibt, wie das Modell geändert werden muss, um das gegebene Ziel zu erreichen. Das Modell selbst hat keine Ahnung von Zielen, es transformiert eine Eingabe nur in eine Ausgabe. Und die Ziele selbst sind zwischen den verschiedenen Lernparadigmen völlig unterschiedlich(wenn ich Regression machen will, kann ich das völlig anders aufziehen, als wenn ich clustern muss).</p>
<p>Wenn wir auf eine schnelle Implementation verzichten wollten, würden wir den internen Zustand gar nicht brauchten (das ist ein reines Implementationsdetail für 99% aller Modelle und die restlichen 1% kann man eh nicht parallel berechnen). Und dann wäre das Design so schon ziemlich gut. Das Problem entsteht erst dadurch, dass wir den internen Zustand einführen, weil wir gerne auf single core Faktor 2 schneller wären. Und weil wir das nun auch noch parallelisieren wollen, muss der Zustand wieder aus dem Objekt raus.</p>
<p>//edit 2 angenommen, ich würde erstmal nur vom std::vector&lt;double&gt; los kommen wollen um das Interface zwar nicht unbedingt besser zu machen, aber einfacher zu verwenden. würde ich dann besser fahren, wenn ich einfach eine Basisklasse für States verwende und dann mit einem boost::polymorphic_cast oder ähnlichem in den verwendenden Klassen einen downcast mache?</p>
<p>oder vielleicht etwas aufgebohrt als sowas:</p>
<pre><code class="language-cpp">//skizze
class State{
private:
    polymorphic_state_wrapper* wrapper;
public:
    State();
    template&lt;class ModelState,class Args&gt;
    void createState(Args args){
         wrapper = new MyStateWrapper&lt;ModelState&gt;(args);
    }
    bool hasState(){
        return wrapper != 0;
    }
    template&lt;class ModelState&gt;
    ModelState&amp; getState(){
        return boost::polymorphic_downcast&lt;MyStateWrapper&lt;ModelState&gt;* &gt;(wrapper)-&gt;state;
    }
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2241029</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2241029</guid><dc:creator><![CDATA[otze]]></dc:creator><pubDate>Sat, 11 Aug 2012 16:57:01 GMT</pubDate></item><item><title><![CDATA[Reply to Wie internen Zustand von Objekt auslagern? on Sat, 11 Aug 2012 19:42:45 GMT]]></title><description><![CDATA[<p>Könntest du nicht eine Art &quot;Super-State&quot; einführen, der Platz für alles hat? Damit hättest du den Kram nur noch einmal. Ist zwar Speicherplatzverschwendung, aber wenn das akzeptabel ist, sollte es eigentlich ziemlich simpel sein für den Rest des Codes.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2241060</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2241060</guid><dc:creator><![CDATA[cooky451]]></dc:creator><pubDate>Sat, 11 Aug 2012 19:42:45 GMT</pubDate></item><item><title><![CDATA[Reply to Wie internen Zustand von Objekt auslagern? on Sat, 11 Aug 2012 21:15:04 GMT]]></title><description><![CDATA[<p>wie meinst du das genau mit dem Super-State? Meinst du so eine Art globalen Zustand bei dem sich jedes Objekt registriert und dann rein schreibt?</p>
<p>also sowas wie: &quot;ich bin objekt x in thread y gib mir mal bitte meinen State&quot;?</p>
<p>also in code ausgedrückt:</p>
<pre><code class="language-cpp">struct MyModel{
private:
    class State{...};
    unsigned int m_objectID;
public:
    MyModel(){
        m_objectID=GlobalState::registerObject();//schreit nach RAII
    }
    ~MyModel(){
        GlobalState::unregister(m_objectID);
    }
    virtual Result foo(some_arg){
        State&amp; state = GlobalState::getState&lt;State&gt;(m_objectID);//automatischer state für jeden thread
        state = ...;
        //was auch immer sonst berechnet werden muss
    }
    virtual Result bar(transformedFoo)const{
        State const&amp; state = GlobalState::getState&lt;State&gt;(m_objectID);
        //nutze state
    }
};
</code></pre>
<p>sieht eigentlich auf den ersten Blick elegant aus. Eventuell macht man da am besten noch eine ordentliche Portion RAII drum und dann erhält man:</p>
<pre><code class="language-cpp">struct MyModel{
private:
    class State{...};
    GlobalState&lt;State&gt; m_state;
public:
    virtual Result foo(some_arg){
        State&amp; state = m_state.state();
        state = ...;
        //was auch immer sonst berechnet werden muss
    }
    virtual Result bar(transformedFoo)const{
        State const&amp; state = m_state.state();
        //nutze state
    }
};
</code></pre>
<p>voll cool eigentlich!<br />
//edit man muss nur irgendwie garantieren, dass die thread-ids identisch bleiben :/. sollte kein Problem sein, solange das Threading von außen kommt. wenn man aber erst in foo() oder bar() threaden würde, wäre das eventuell finster...</p>
<p>//edit X bwaah jetzt ist aber nicht mehr kodiert, dass bar nur nach foo aufgerufen werden kann. arrghl</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2241077</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2241077</guid><dc:creator><![CDATA[otze]]></dc:creator><pubDate>Sat, 11 Aug 2012 21:15:04 GMT</pubDate></item><item><title><![CDATA[Reply to Wie internen Zustand von Objekt auslagern? on Sat, 11 Aug 2012 21:56:12 GMT]]></title><description><![CDATA[<p>Das meinte ich eigentlich nicht.^^ Das Problem war doch, dass der Typ von &quot;State&quot; abhängig ist von A. Du hast dann den Zustand rausgezogen und vector&lt;double&gt; als &quot;generische&quot; Schnittstelle genommen. Meine Idee war jetzt, einfach einen State zu machen, der für alle A funktioniert. Dann hat man vielleicht ein paar Stellen drin, die nur manchmal gebraucht werden, aber man muss da nichts mehr</p>
<blockquote>
<p>später aus dem Ding wieder raus popeln.</p>
</blockquote>
<p><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/2241086</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2241086</guid><dc:creator><![CDATA[cooky451]]></dc:creator><pubDate>Sat, 11 Aug 2012 21:56:12 GMT</pubDate></item><item><title><![CDATA[Reply to Wie internen Zustand von Objekt auslagern? on Sat, 11 Aug 2012 22:05:24 GMT]]></title><description><![CDATA[<p>otze schrieb:</p>
<blockquote>
<p>jetzt ist aber nicht mehr kodiert, dass bar nur nach foo aufgerufen werden kann. arrghl</p>
</blockquote>
<p>Mach doch so etwas:</p>
<pre><code class="language-cpp">Result myFunc(A&amp; a, B&amp; b,Arg&amp; some_arg){
     FooTransformed&lt;Result&gt; fromFoo = a.foo(some_arg);
     FooTransformed&lt;Result&gt; temp    = b.transform(temp);
     Result res = a.bar(temp);
     return res;
}
</code></pre>
<p>FooTransformed&lt;Result&gt; ist eine Klasse die nur aus Result besteht. Die einzige Eigenschaft, die sie hat, ist, dass sie nur von A erzeugt werden kann:</p>
<pre><code class="language-cpp">struct FooTransformed&lt;Result&gt; {
   Result* operator-&gt;() { return &amp;r; }
   friend class A;
private:
   Result r;
   FooTransformed(Result r) : r(r) {}
};
struct A{
    virtual std::size_t stateSize(some_arg);
    FooTransformed&lt;Result&gt; foo(some_arg, State&amp; state)
    { return FooTransformed(foo_impl(arg, state)); }
    virtual Result bar(FooTransformed&lt;Result&gt;, State const&amp; state)=0;
protected:
    virtual Result foo_impl(some_arg, State&amp; state)=0;
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2241089</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2241089</guid><dc:creator><![CDATA[footrans]]></dc:creator><pubDate>Sat, 11 Aug 2012 22:05:24 GMT</pubDate></item><item><title><![CDATA[Reply to Wie internen Zustand von Objekt auslagern? on Sun, 12 Aug 2012 08:27:01 GMT]]></title><description><![CDATA[<p>cooky451 schrieb:</p>
<blockquote>
<p>Das meinte ich eigentlich nicht.^^ Das Problem war doch, dass der Typ von &quot;State&quot; abhängig ist von A. Du hast dann den Zustand rausgezogen und vector&lt;double&gt; als &quot;generische&quot; Schnittstelle genommen. Meine Idee war jetzt, einfach einen State zu machen, der für alle A funktioniert. Dann hat man vielleicht ein paar Stellen drin, die nur manchmal gebraucht werden, aber man muss da nichts mehr</p>
<blockquote>
<p>später aus dem Ding wieder raus popeln.</p>
</blockquote>
<p><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>Das ist bei der Variabilität schon schwierig (wir haben im worst case eine dynamische Anzahl von matrizen, vektoren, skalaren und anderem Kleinkram...). Wäre sicherlich besser als die jetzige Version...andererseits ist alles besser als die jetzige Version. Und der Ansatz führt noch immer nicht zu Code, bei dem die Zustandsvariablen ordentliche Namen haben.</p>
<p>hmm...</p>
<p>@footrans ja, an sowas habe ich auch schon gedacht. Es gibt an der Stelle aber eine einfachere Lösung, die man eventuell verwenden könnte:</p>
<pre><code class="language-cpp">Result myFunc(A&amp; a, B&amp; b,Arg&amp; some_arg){
     Result fooResult = a.foo(some_arg);
     Result temp    = b.transform(temp);
     Result res = a.bar(fooResult,temp);
     return res;
}
</code></pre>
<p>da bar die Ableitung der Funktion foo ist und wir häufig den Fall haben, dass wir die Ableitung in der form f'(x)=g(f(x)) ausdrücken können, macht es sinn, an der Stelle den Funktionswert zu erwarten.</p>
<p>Muss ich aber mit meinen Leuten abklären, was die davon halten.</p>
<p>OT:</p>
<p>Ich bin noch immer unentschlossen. Der globale State, wie ich ihn vorgeschlagen habe ist zwar nett, insbesondere weil er die Implementationsdetails nicht nach außen trägt, andererseits sehe ich schon jetzt, dass das nur eine leaky-abstraction ist und ich in manchen Fällen trotz des versteckten Zustandes dafür Sorge tragen muss, dass ich nicht aus versehen wichtige Dinge überschreibe.</p>
<p>Genau so ginge ja auch:</p>
<pre><code class="language-cpp">struct MyModel{
private:
    class State{...};
public:
    virtual Result foo(some_arg, AbstractState&amp; state)const{
        State&amp; state = state.get&lt;State&gt;();
        state = ...;
        //was auch immer sonst berechnet werden muss
    }
    virtual Result bar(transformedFoo, AbstractState const&amp; state)const{
        State&amp; state = state.get&lt;State&gt;();
        //nutze state
    }
};
</code></pre>
<p>Arrgh Entscheidungen...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2241139</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2241139</guid><dc:creator><![CDATA[otze]]></dc:creator><pubDate>Sun, 12 Aug 2012 08:27:01 GMT</pubDate></item></channel></rss>