Constness-Aushebelung verhindern
-
Kahino schrieb:
Das private in Klassen soll z.B. nicht davor schützen, das jemand eine private-variable manipuliert, sondern nur das die Kapselung im OO-Sinne gewahrt wird
Ich wollte hier eigentlich keine konkreten Aussagen behandeln aber ... wie bitte?
Die Kapselung im OO sinne beinhaltet doch, dass man sie von außen nicht ändern kann, wie kann private dann nciht dafür verantwortlich sein?
Hast du dir mein Posting insgesamt betrachtet? Anscheinend nicht, sonst würdest du feststellen, das ich von dem Schreibschutz auf Implementierungsebene geschrieben habe. Nochmal für dich: das private ist nicht für Implementierungs-Hiding zuständig! Da kannst du dich auf den Kopf stellen, das wird deshalb nicht anders. Das private ist ein reiner Formalismus auf OO-Sprachebene und der User bekommt deshalb lediglich beim Kompilieren die Meldung "Sorry, aber da darfst du nicht zugreifen!". Mehr nicht. Das private steht ja nach dem Kompilieren nirgends im Speicher...
-
Dawg schrieb:
...Wenn die Sprache ordentlich definiert wäre, hätte man bei meinem Problem beides: Man hätte die eleganteste Lösung und den wenigsten Aufwand: Die Rückgabe einer const-Referenz: Lesezugriff erlaubt, Schreibzugriff nicht möglich. So, wie ich es haben wollte....
Aber so ist es doch auch: Man kann eine const-Referenz zurückgeben.
Dawg schrieb:
...
Simon2 schrieb:
Dawg schrieb:
Klar, mit Kopien geht's natürlich immer. Fragt sich nur, ob das so gut/effektiv ist, jedesmal die Daten alle komplett rüberzuschaufeln.
Das wäre bei der getter-Methode nicht prinzipiell anders (nur, dass Du die Elemente einzeln kopierst - dafür aber ggf. öfter).
Wieso? Bei einer Rückgabe einer const-Referenz würde ich doch nur jeweils die Speicheradresse, also ein simples int, kopieren. Bei einer echten Kopie habe ich bei einem vector<double> mit 100 Einträgen schonmal 800 Byte statt nur vier...
Wie Du zwischen meinem Post und Deinem anscheinend vergessen, dass an dieser Stelle über die "getter-Variante" geredet wurde, die Artchie vorgestellt hat, die Dir aber zu aufwendig war.
Dawg schrieb:
...Dann frage ich mich, wieso wir überhaupt noch private und protected haben. Wieso nicht gleich überall public nehmen. ...
Vielleicht solltest Du mal über den Unterschied zwischen
- dem Vorhandenseins eines "Notausknopfs" und
- der Nichtexistenz der Maschine
nachdenken.
Ich persönlich wäre (auch nach Dekaden der Programmiererfahrung) nie derart überzeugt von meiner eigenen Unfehlbarkeit und Weitsicht, "Notausknöpfe" prinzipiell verbieten zu wollen.Dawg schrieb:
...Man hätte nur den const_cast weglassen müssen und alles wäre gut. Es hat ja schließlich einen Grund, wieso etwas als const zurückgegeben wird....
Und Du glaubst, const_cast wäre nur durch reinen Zufall in den Standard gerutscht?
Bloß weil Du ihn noch nie gebraucht hast, bedeutet es nicht, dass er überflüssig ist - es bedeutet eher, dass es noch Ecken in der Programmiererwelt gibt, in die Du noch nicht vorgedrungen bist.
Es ist ein sehr gefährliches Werkzeug, dass aber in bestimmten Ausnahmesituationen gebraucht wird.Gruß,
Simon2.
-
Das const ist aber kein Implementierungs-Const, sondern ein Information-Const. Naja, habe jetzt keine anderen Begrifflichkeiten zur Hand. Aber so wird es auch jeder verstehen.
Man sollte bedenken, das die Sprache nicht dafür da ist, Implementierungen zu schützen. Es geht um formalistem. Das private in Klassen soll z.B. nicht davor schützen, das jemand eine private-variable manipuliert, sondern nur das die Kapselung im OO-Sinne gewahrt wird - mehr nicht! Deshalb ist es natürlich i.O. das es const_cast gibt. Weil die Intention von const nicht bedeutet, das es eine Hochsicherheitstrackt mit ner Festung ist. Da muß was anderes her: eine CPU-Erweiterung oder OS-Feature. Weil das wäre ein Implementierungsdetail.
Tja, auch wenn ich alles zitiere ändert sich nichts und das glücklicherweise auch ohne mich auf den Kopf stellen zu müssen.
Was spielt das für eine Rolle ob irgendwo im Speicher private steht oder nicht?
Was du vor der Kompilierung machs soll ja schließlich bestimmen wie das Ergebnis nach der Kompilierung arbeitet.Die Objektorientierung ist dabei lediglich ein optionales Abstraktionsmodell das man Verwenden kann oder auch nicht.
Solche Konzepte als Formalismus abzustempeln ist nicht falsch, doch darf man nicht vergessen, dass es sich bei diesem Formalismus(unabhängig von Objektorientierung oder irgendeiner spezifischen Sprache) nunmal um DAS Werkzeug handelt um die gewünschen Arbeitsvorgänge zu beschreiben.Schließlich soll ja alles wohl definiert und keine Glückssache sein oO, (man stelle sich sowas mal in der Mathematik vor
).
Unstimmigkeiten kann es immer wieder mal geben, doch wenn man bei irgendwas behaupten kann das Ergebnis ist garantiert anders als man es vorher definiert hat, läuft da gehörig was schief und so wird es ja wohl nicht sein.
Und das gilt sicherlich auch für einige andere Gebiete, fernab der Programmierung.In kurz:
Habe sehr wohl deinen ganzen Post gelesen, Jedoch sind Meinungen wie etwas sein sollte alles andere als absolut.
-
Kahino schrieb:
...Was spielt das für eine Rolle ob irgendwo im Speicher private steht oder nicht?...
In dem Zusammenhang hatte ich es so verstanden: Der "Zugriffsschutz", den "private" bietet, ist (relativ problemlos) zu umgehen - er schützt also nicht gegen "Hacks"/"Macchiavelli"/... .
Das hätte man anders implementieren können, wenn "...private im Speicher steht..." und dort durch irgendwelche Laufzeitmechanismen (Runtime, OS, CPU, ....) geprüft/sichergestellt wird.Im Zusammenhang der Diskussion ist das wesentlich, weil der Threadersteller gerne ein "un-hackbares const" gehabt hätte und er auf Gegenargumente einen Vergleich zu "private" zog.
Gruß,
Simon2.
-
Nochmal zum const_cast: Der ist nur und alleine dafür da, um nicht const-korrekte Klassen mit const-korrekten Klassen verwenden zu können. Das heißt, wenn wir wissen, dass eine Methode eines Objektes das Objekt nicht ändert, aber leider nicht als const klassifiziert wurde, dann dürfen wir den const_cast machen. andernfalls nicht.
-
otze schrieb:
Nochmal zum const_cast: Der ist nur und alleine dafür da, um nicht const-korrekte Klassen mit const-korrekten Klassen verwenden zu können. Das heißt, wenn wir wissen, dass eine Methode eines Objektes das Objekt nicht ändert, aber leider nicht als const klassifiziert wurde, dann dürfen wir den const_cast machen. andernfalls nicht.
Aehmmm ... naja ... hmmm ... Wenn ich z.B. in meiner Datenhaltungsschicht eine Suchfunktion habe, die intern einen Index veraendert und anschliessend wieder zuruecksetzt, dann kann ich das const wegcasten, damit die Methode trozdem const ist. Eine andere Moeglichkeit ergibt sich durch das Schluesselwort mutable.
Bei diesen und Aehnlichem verweise ich gern auf: http://www.parashift.com/c++-faq-lite/classes-and-objects.html#faq-7.7 . Const hilft, aber schuetzt nicht vor Fehler.
-
In dem Zusammenhang hatte ich es so verstanden: Der "Zugriffsschutz", den "private" bietet, ist (relativ problemlos) zu umgehen - er schützt also nicht gegen "Hacks"/"Macchiavelli"/... .
Das hätte man anders implementieren können, wenn "...private im Speicher steht..." und dort durch irgendwelche Laufzeitmechanismen (Runtime, OS, CPU, ....) geprüft/sichergestellt wird.Im Zusammenhang der Diskussion ist das wesentlich, weil der Threadersteller gerne ein "un-hackbares const" gehabt hätte und er auf Gegenargumente einen Vergleich zu "private" zog.
Jo, ersteinmal kompiliert ist das Ergebnis einfach nur ein Block Daten den man halt beliebig manipulieren kann, vorausgesetzt man hat die Zugriffsrechte auf die Datei. Doch das man von außen nun diesen Kram verändern kann hat das nichts damit zu zun wie das zu manipulierende Programm bei Ausführung selbst arbeitet.
Denn dies hängt ja, wenn man bei dieser Formulierung bleiben möchte, vom verwendeten Formalismus ab mit dem man das Verhalten umschreibt.
Und wenn wir uns über Mittel der Formulierungsebene unterhalten ist das ja auch die Ebene um die es geht.
Also bei der Frage ob man Elemente der Formulierungsebene durch spezifikationen in der Selben Formulierungsebene in welcher Art auch immer manipulieren kann bzw. nicht kann/ nicht können sollte spielen halt nur Regeln der Formulierungsebene Eine Rolle.Wenn man ein Auto baut kümmert man sich vielleicht um die Frage wie man verhindert, dass die internen Bauteile nicht den Benzintank aufreißen.
Würde in einem Autodesigne ein Spitzer Eisenstab vorm Bezintank angelegt der nach vorne gerammt wird soballd man losfährt, würde dieses Designe die Qualitätsprüfung niemals überstehen, somit nicht konstruiert sondern überarbeitet werden.
Doch beduetet dies ja nicht, das der Besitzer eines bereits konstruierten Autos sowas nicht vielleicht lustig finden könnte und dies dann selbst einbaut oder vielleicht einfach ein Unfall passiert.
Natürlich kann das Auto auf Grund einer unsauberen Fertigung auch explodieren, ungereimtheiten gibt es halt immer wieder mal
unabhängig davon ob jetzt einfach ein Fehler auftrag oder die Qualitätskontrolle irgendwie umgangen wurde.Mal so als kleine spontane Analogie :xmas2:
ungeprüft ob dies jetzt so 100 prozentig passt.