Proxys und const-correctness



  • vielleicht solltest du das nächstes mal die Funktionen nicht virtuell machen.

    Aber dann hast du ja gegen die Rahmenbedingungen verstoßen, habe ich gar nicht bemerkt. Wenn du die Methoden nicht virtuell hast, dann ist doch klar, dass der von mir zitierte Paragraph gültig wird und Methoden die nicht benutzt werden auch nicht instantiiert werden.

    Dann ist die Lösung aber auch wieder falsch.



  • Sone schrieb:

    Dann ist die Lösung aber auch wieder falsch.

    hast ja recht *wuschelwuschel*



  • knivil:

    Ich habe C++-Programmierstil mit Java-Programmierstil anhand deines Interface/Proxy/ConstProxy-Beispiels. Voellig emotionslos.

    Moment, meinst Du, Du hältst meinen Code für C++- mit Java-Stil gemischt (oder auch nur letzteres) oder dass Du es selbst so nutzt? Ich gehe Mal vom ersteren aus.

    Und dann ist das eben für diesen Teil ein Stil, den man auch in Java so nutzen würde. Aber das heißt ja nicht gleichzeitig, dass es schlecht ist oder der Code dadurch dequalifiziert wird. Es gibt in meinen Augen an der Stelle keine bessere Lösung für meine Praxis. Und dass GoF-Patterns nicht immer optimal für C++ sind, ist doch ein alter Hut. Nicht immer impliziert aber eben "manchmal eben doch".

    Zudem werden Proxys in C++ ja durchaus eingesetzt. Das Einzige, was hier stört, ist ja, dass ich noch ein Interface drüberpappe. Dann müsste man ja sagen, dass dynamische Polymorphie java-like ist? Oder Interfaces? Also basierend auf den Aussagen hier komme ich zu keiner konsistenten Definition von "java-like", die ich halt bräuchte, wenn das so schlimm wäre, dass man es auf gar keinen Fall in C++-Code einsetzen darf (wirkt für mich so, als wäre das hier ständig gefordert, vielleicht vertue ich mich da).

    Ok, aber zum Thema: Wer ein const Interface* erwartet, kann den ConstProxy erhalten, dafür ist der const Interface* operator() doch da. Somit verhält sich ConstProxy wie ein Erbe von Interface. Daher wird is_a quasi simuliert. Besser gesagt, wird "ConstProxy is a const Interface" simuliert (na ja, jedenfalls für Referenz- und Zeigerparameter). Geschieht nur nicht klassisch erstklassig durch Vererbung. Aber Vererbung würde ja auch sagen "ConstProxy is an Interface" und das ist ja keine korrekte Aussage. Eigentlich bräuchte man so was wie " : public const Interface" oder irgendwo anders einen Qualifizierer, aber da C++ das nicht anbietet (hätte ja auch wieder Probleme), muss man es anders tun und facepalms Lösung scheint das so weit doch zu tun.



  • Hi,

    nach wie vor an einer Antwort interessiert. 🙂

    Mir ist jetzt jedoch auch aufgefallen, dass das Interface mir nichts bringt *schäm*. Warum?

    Weil ich an der Stelle, wo Proxy ODER eigentliches Objekt übergeben werden, ein logischer Konflikt vorliegt. Denn wie soll man bitte gestalten, dass man entweder Proxy oder eigentliches Objekt erhält? Ein Proxy ist ja kopierbar, er verweist ja nur auf das Objekt bzw. leitet alles weiter. Die Range selbst aber nicht. Wenn ich also ein Interface* habe, muss ich höllisch aufpassen, da dort auf keinen Fall ein Zeiger auf einen Proxy reinkommen darf, weil man den Proxy ja ständig by value übergibt, da die Kopie günstig und erwünscht ist.

    Jetzt habe ich dämlicherweise gemerkt, dass es echt schnell passieren kann, dass man eben so einen Zeiger übergibt. 👎 Insofern schmeiß ich das Interface jetzt in der Tat weg...

    Designproblem bleibt jedoch der Falll, dass man entweder Proxy oder Referenz auf Objekt (ohne Proxy-Indirektion) übergeben kann... Das habe ich jetzt über die Indirektion gelöst, dass es eine Struktur Occurence gibt, die sowohl Zeiger auf ActualObject als auch ein Objekt (ohne Zeiger natürlich) des Proxys hat. Wenn der Zeiger nullptr ist, bedient man sich als Anwender dann dem Proxy...

    Echt unschön, hat jemand eine Idee, wie ich das besser löse? Man könnte einen Proxy machen, der einfach alles weiterleitet, diesen und den eigentlichen Proxy von einer gemeinsamen Basis ableiten lassen und dann gezwungen werden immer einen der beiden Proxys (wovon der eine ja quasi nur Zeiger ist) zu übergeben... aber das ist doch auch eklig und ich muss wieder Polymorphie nutzen 😞



  • Eisflamme schrieb:

    Ein Proxy ist ja kopierbar, er verweist ja nur auf das Objekt bzw. leitet alles weiter.

    Das passiert, wenn man sich nicht an meine Hinweise hält.

    Der Fehler:

    Man muss jedoch auch noch operator const Interface* überladen, nicht jeder mag Referenzen. Aber sonst scheint das okay zu sein.

    Proxy = Interface = Noncopyable = zeigt immer aufs gleiche Objekt = Referenz

    Du kannst von mir aus den operator& überladen, damit er ein const Interface* zurückgibt. Aber Proxy=Interface, nicht Proxy=Interface*

    Ich finde es aber toll, dass du es auch ohne Vererbung gelöst hast. Das ist nämlich weitaus die bessere Variante.



  • Na ja, es waren viele Hinweise und ich hatte ja auch einige Fragen dazu, wie ich es dann anwenden soll, weil ich es nicht ganz verstand. 🙂

    Aber ich glaube, wir haben hier auch eine andere Vorstellung vom Proxy an sich. Jedenfalls brauche ich den Proxy (oder wie man ihn dann gerne nennen würde) bei mir für einen Zugriff auf ein bereits bestehendes Objekt, das sich eben in einem Baum befindet. Ein sich in einem Baum befindliches Klassenobjekt hat bei mir Verhaltensunterschiede zu einer solchen Klasse, die nicht in einem Baum abgelegt ist.

    Daher will ich eben so ein Proxy-Objekt nutzen, über das man das im Baum befindliche Objekt unter Berücksichtigung der Phänomene - da besagtes Objekt im Baum ist - ändern kann. Die Klasse des eigentlichen Objekts soll aber unberührt bleiben, weil man die eben auch außerhalb vom Baum nutzen kann.

    Daher fand ich so einen "Proxy"-Ansatz ganz chic, die eigentliche Klasse bleibt unberührt und für andere Kontexte nutzbar, sobald die Elemente im Baum vorkommen, nutzt man aber den Proxy für den Zugriff.

    Nur ist der Proxy dann eben Referenz auf ein bestehendes Objekt. Wie würdest Du das denn lösen?



  • So isch des eben beim Software entwickeln. Es ist und bleibt ein Prozess 🙂 Ständig dran arbeiten und verbessern. Zum Schluss wirst du aber mit etwas schickem belohnt werden und zufrieden sein.



  • Ja, ist wirklich ein Prozess, ich habe nur das Gefühl, dass ich nicht wirklich weit bin und ich werde mich auch nicht jahrzehntelang damit befassen können. 😞 Zudem glaube ich, dass - angenommen, es gäbe einen Schluss - ich immer hier ins Forum kommen würde, den Code posten würde und er zerrissen würde. Dann wäre ich aber nicht wirklich zufrieden. Von daher finde ich, dass Deine Aussage "Zum Schluss bist Du zufrieden" nicht so stimmt. 😃

    Aber na ja, mein Design jetzt ist schon deutlich besser als vorher. Und wenn man sich so ansieht, was für kommerzielle Softwareprojekte mit schlimmen Code rumschwirren, darf man doch eigentlich schon sehr zufrieden sein, wenn man die selbst gesetzten Ziele bzgl. Änderbarkeit und Erweiterbarkeit gut hinbekommt, oder?

    Die Frage bzgl. der Übergabe solcher nicht-erbenden Proxy-Klassen an jemand anderen habe ich Mal verlagert: http://www.c-plusplus.net/forum/319547


Anmelden zum Antworten