const in Java und interface's ...
-
CStoll schrieb:
Es ist eine Zusicherung für mich, daß jemand anderes meine Objekte nicht ändern wird. Wenn ich einer fremden Funktion ein 'const test&' übergebe, kann diese nur die const-Methoden meiner Klasse verwenden.
Hm, somit können die Eigenschaften eine const-Objekts von einer fremden Funktionen nicht oder oder nur temporär geändert werden. So hat der Programmierer also Sicherheit, dass an seinem Objekt keine ungewollten Veränderungen durchgeführt werden.
Aber was soll ein const-Methode? So, wie ich das verstehe, habe ich innerhalb einer solchen Methode keine Möglichkeit Eigenschaften von this zu ändern, oder? Aber, was bringt mir das? Ich weiß doch selbst am besten, was ich verändern darf und welche Veränderungen sinnvoll ist.
Ich persönlich finde die Handhabung von const in C oder C++ auf den ersten Blick etwas verwirrend. So wie ich das überschaue, kann man dieses Schlüsselwort ja "überall" hinschreiben, und es hat überall eine andere Wirkung. Und ich hatte auch noch keine Probleme damit, dass es dieses Schlüsselwort und seine Möglichkeiten in Java nicht gibt.
-
Varus schrieb:
CStoll schrieb:
Es ist eine Zusicherung für mich, daß jemand anderes meine Objekte nicht ändern wird. Wenn ich einer fremden Funktion ein 'const test&' übergebe, kann diese nur die const-Methoden meiner Klasse verwenden.
Hm, somit können die Eigenschaften eine const-Objekts von einer fremden Funktionen nicht oder oder nur temporär geändert werden. So hat der Programmierer also Sicherheit, dass an seinem Objekt keine ungewollten Veränderungen durchgeführt werden.
Aber was soll ein const-Methode? So, wie ich das verstehe, habe ich innerhalb einer solchen Methode keine Möglichkeit Eigenschaften von this zu ändern, oder? Aber, was bringt mir das? Ich weiß doch selbst am besten, was ich verändern darf und welche Veränderungen sinnvoll ist.
Die fremde Funktion darf meine Objekte zwar nicht ändern, aber sie darf Statusinformationen meiner Objekte auslesen - und damit sie dafür nicht an meinen Methoden vorbeigehen muß, gibt es const Methoden (die dürfen zwar interne Daten auslesen, aber nicht ändern - und von einem konstanten Objekt dürfen nur const-Methoden aufgerufen werden).
Sprich: Wer das Objekt ändern darf, bekommt eine "normale" Referenz übergeben und kann alle Methoden des Objekts nutzen. Wer ein Objekt nicht verändern darf, bekommt eine const-Referenz und darf nur mit dem const-Methoden umgehen (oder das Objekt kopieren und sich an der Kopie austoben).
-
Interfaces und abstrake Klassen unterscheiden sich letztendlich eigentlich nur von der Semantik her. Ich persönlich finde es eigentlich schon gut, dass es das in Java gibt, da man so eben doch semnatische Unterschiede kennzeichnen kann. Ansonsten ist es aber auch kein Weltuntergang, dass es das in C++ nicht gibt. Egal.
Und bei der const-Geschichte denke ich auch, dass es in Java einfach aus Gründen der Einfachheit weggelassen wurde, bzw. dass es nicht so wie in C++ ist. In Java gibts ja auch das Schlüsselwort "final", was im Prinzip das Äquivalent zu const darstellen soll, aber natürlich lange nicht so weitreichend. Den Mechanismus so wie in C++ zu simulieren (bzw. es zu versuchen) macht IMHO tatsächlich keinen Sinn, da soetwas eben einfach nicht vorgesehen wurde.
Der Mechanismus ist IMHO schon sinnvoll und praktisch, aber auch hier ist das analog kein Weltuntergang dass es das in Java nicht gibt
-
CStoll schrieb:
Sprich: Wer das Objekt ändern darf, bekommt eine "normale" Referenz übergeben und kann alle Methoden des Objekts nutzen. Wer ein Objekt nicht verändern darf, bekommt eine const-Referenz und darf nur mit dem const-Methoden umgehen (oder das Objekt kopieren und sich an der Kopie austoben).
OK, danke für die Erklärung. Bin ich wieder ein Stückchen schlauer
-
CStoll schrieb:
...(oder das Objekt kopieren und sich an der Kopie austoben).
gibts da in c++ nicht dieses const cast zeugs?
-
nachgefragt schrieb:
CStoll schrieb:
...(oder das Objekt kopieren und sich an der Kopie austoben).
gibts da in c++ nicht dieses const cast zeugs?
Ja, gibt es auch - aber wer sowas verwendet, soll in der Hölle schmoren.
@nep: Interfaces braucht man in C++ nicht wirklich. Die wurden afaik nur in Java eingeführt, um eine (stark abgespeckte) Version von Mehrfachvererbung zu ermöglichen, ohne die normale Klassenhierarchie unnötig zu verkomplizieren.
-
Interfaces sind in Java auch der einzige Weg für Polymorphie. Deshalb sehen Hierachien in Java meistens komplett anders aus als in C++. Man hat deutlich mehr Vererbung und implementiert sehr viele Interfaces.
zB eine delegate/functor wird als Interface implementiert. Es ist ein ziemlich anderer Ansatz als man in C++ hat wo man vererbung fast mit der Lupe suchen muss.
const-correctness wurde nicht eingeführt, da es die komplexität der sprache erhöhen würde. inwieweit das argument zu zeiten von generics und annotations noch zählt, sei mal dahin gestellt. und jetzt hat man probleme es einzubauen weil es den bytecode ändern würde - und solche features werden aus verständlichen gründen sehr sehr ungern eingebaut.
-
@kasf: leider gescheitert, aber da gut getarnt kriegst du von mir trotzdem eine 5/10 <°))))o><
@const: das sieht für mich nur wie ein fieser workaround aus um die mischung von objektorientiertem und funktionalem code in c++ vernünftig auf die reihe zu kriegen. die interne repräsentation eines objekts sollte nur das objekt selbst kennen demnach sollte es auch keine "(nicht-) verändernden" methoden geben
-
Ich weiß, dass man Interfaces nicht braucht in C++. Hab ich ja auch nicht behauptet
Ich finde es trotzdem nicht schlecht, da es halt einen gewissen semantischen Unterschied darstellt, ob man nun ein Interface oder eine abstrakte Klasse verwendet. Aber wie gesagt, in C++ kommt man genauso zum Ziel.
-
hmmm++ schrieb:
@kasf: leider gescheitert, aber da gut getarnt kriegst du von mir trotzdem eine 5/10 <°))))o><
? Auf was beziehst du das ?
-
KasF schrieb:
hmmm++ schrieb:
@kasf: leider gescheitert, aber da gut getarnt kriegst du von mir trotzdem eine 5/10 <°))))o><
? Auf was beziehst du das ?
auf deinen trollversuch
-
-
Es ist eine Zusicherung für mich, daß jemand anderes meine Objekte nicht ändern wird. Wenn ich einer fremden Funktion ein 'const test&' übergebe, kann diese nur die const-Methoden meiner Klasse verwenden.
Das habe ich auch noch nie verstanden.
Mir, als Benutzer einer Klasse, ist es total egal, ob intern in der Klasse irgendwelche privaten Felder veraendert werden.
Umgekehrt, weis ich, als Programmierer der Klasse, dass wenn der Benutzer eine get Methode aufruft, er keine Interna veraendern kann. Es seih denn ich gestatte es ihm.
Also wozu dann const-Methoden?Den Weg mit "nur get-Interface" ist dazu da einen Immutable und einen Mutable -Typ zu haben. Das hat den Vorteil, dass die immutable Klasse einfacherer uebergeben werden kann, also weniger komplex sein kann.
Siehe dazu String und StringBuilder/StringBuffer.In Java gibts ja auch das Schlüsselwort "final", was im Prinzip das Äquivalent zu const darstellen soll, aber natürlich lange nicht so weitreichend.
Nein, ist es nicht. C++ const und Javas final verhalten sich anders. In C++ ist const auch abhaenig vom Kontex, in Java ist final einfach nur ein Referenz-Konstant.
-
Of course, some consider the STL a bletcherous wart on the backside of C++, and others consider C++ a bletcherous wart on the back side of ComputerScience--so that would make const_iterator a ThirdDegreeWart
ROFL
-
DEvent schrieb:
Of course, some consider the STL a bletcherous wart on the backside of C++, and others consider C++ a bletcherous wart on the back side of ComputerScience--so that would make const_iterator a ThirdDegreeWart
ROFL
ja, c2.com ist nur noch geil
alles sehr lesenswert...
-
Nehmen wir doch mal als Beispiel die Klasse String.
Die kann ich einfach nich veraendern. Egal was ich mache. Es gibt dafuer einfach kein Interface. Wenn ich Strings manipulieren muss, dann muss StringBuilder/StringBuffer her:StringBuilder b = new StringBuilder(meinstring); b.insert b.append b. sonstwas... meinstring = b.toString();
Wo wuerde nun ein C++-Hacker gerne ein const in der String-Klasse sehen?
-
DEvent schrieb:
In C++ ist const auch abhaenig vom Kontex, in Java ist final einfach nur ein Referenz-Konstant.
final ist in java auch sehr stark vom Kontext abhängig.
final class Foo { final void bar(final Baz baz) { final int i=5; } }
-
DEvent schrieb:
Es ist eine Zusicherung für mich, daß jemand anderes meine Objekte nicht ändern wird. Wenn ich einer fremden Funktion ein 'const test&' übergebe, kann diese nur die const-Methoden meiner Klasse verwenden.
Das habe ich auch noch nie verstanden.
Es geht um viel mehr. Auch als Hilfe für einen selber. Wie allen bekannt sein sollte, ist das übergeben von Referenzen wesentlich effizienter als Kopien. Jetzt schreibst du dir eine Funktion die etwas mit diesem Objeket machen soll, zB Ausgeben.
Da du gar nicht vor hast dieses Objekt in der Funktion zu verändern deklarierst du den Parameter natürlich als const-Ref. ( Und jetzt nicht sagen ich pass schon auf das ich nicht falsches in der Funktion mache, bei komplexeren Funktion ist da schnell mal was passiert, zudem ist es doch viel schöner wenn man gar nicht drauf aufpasse muss )
Nun hast du aber das Problem das du zB keine get-Methoden aufrufen könntest die nicht const sind. Deswegen deklarierst du die Funktion als const und stellst für dich selber auch ne Sicherheit auf, dass du this in get() nicht änderst.Es geht aber noch weiter. Häufig stellst du zwei Elementfunktion zur Verfügung, eine const und eine normal. Dadurch hast du auch die Möglichkeit die Funktion im Rückgabewert zu verändern. Nehmen wir mal an du hast ein Matrix Klass oder einfach deinen eigenen Vector:
class MyIntVec { private: int *data; public: int& operator[](size_t i) { return data[i]; } };
Nun arbeitest du ganz normal damit:
MyIntVec vec; // fill vec cout << vec[3]; vec[3] = 23;
Alles noch ok, aber was ist wenn du ein konstantes Objekt haben willst, das irgendwas repräsentieren soll und deswegen fest und unveränderbar sein muss:
const MyIntVec const_vec(othervec.begin(),othervec.begin() + 4); cout << const_vec[3]; // funktioniert nicht
Der Compiler lässt das nicht zu, da er nicht weiß ob op[] nicht doch das Objekt ändern würde.
Ist das nicht toll, das er das für einen prüft.
Nun noch ein :int& operator[](size_t i) const { return data[i]; }
und es funktioniert.
Nun ist op[] const zwar bitweise Konstant aber nicht logisch Konstant.const_vec[3] = 3; // ohh
->
const int& operator[](size_t i) const { return data[i]; }
Schon besser
Das sind zwar einfach Beispiele aber es sollte reichen. Ein const mehr hilft einem sehr zumal man so die Möglichkeit hat auf konstante und nicht konstante Objekte unterschiedlich zu reagieren ...
-
Es geht um viel mehr. Auch als Hilfe für einen selber. Wie allen bekannt sein sollte, ist das übergeben von Referenzen wesentlich effizienter als Kopien. Jetzt schreibst du dir eine Funktion die etwas mit diesem Objeket machen soll, zB Ausgeben.
Da habe ich aufgehoert zu lesen. In Java werden zu 90% Referenzen uebergeben (bis auf die Primitiven). Komischer weise wird das ganz einfach ueber das Interface der Klasse geloest.
final ist in java auch sehr stark vom Kontext abhängig.
Ja, schon klar. Aber es ging eigentlich um Variablen/Parameter. Da ist final eindeutig, anders als das C++ const.
-
DEvent schrieb:
Ja, schon klar. Aber es ging eigentlich um Variablen/Parameter. Da ist final eindeutig, anders als das C++ const.
in gewisser weise nicht
final int == const int
und
final Foo == Foo* constaber ja: das was man in C++ mit const bewerkstelligt gibt es in java nicht.
Mir, als Benutzer einer Klasse, ist es total egal, ob intern in der Klasse irgendwelche privaten Felder veraendert werden.
Genau das ist im Sinne der const-correctness falsch. wenn ich eine lila kuh and die funktion: mache_ein_bild_von_kuh() übergebe, erwarte ich wieder eine lila kuh zu bekommen und keine grüne. const correctness garantiert mir genau das. wenn ich sage: niemand darf meine lila kuh umfärben, sprich:
Kuh lila; Kuh const& konstante_lila_kuh=lila;
dann weiss ich, dass meine lila kuh immer lila bleiben wird.
das ist deshalb vorhanden da man bei primitiven typen ja nichts ändern kann:
int i=3; gib_zahl_aus(i);
i kann sich ja nicht ändern. ich habe die garantie dass i auch nach dem ausgeben 3 ist, weil gib_zahl_aus ja per value nimmt, es kann also i nicht ändern.
bei
Kuh lila=new Kuh(); gib_kuh_aus(lila);
ist diese garantie plötzlich weg.
also haben sich ein paar leute gedacht: eigentlich ist es garnicht so dumm wenn gib_kuh_aus die kuh nicht ändern darf. sprich: wir schützen uns gegen murphy.
dieser schutz ist aber nicht zwingend erforderlich. er erleichtert es sicheren code zu schreiben, aber es ist nicht mehr als ein versprechen. denn um alle verbote kommen wir herum - machiavelli lässt grüßen.
java ist den weg gegangen: es ist nicht 100% erforderlich, also sparen wir uns dieses ganze konzept und halten die sprache simpel.
Da habe ich aufgehoert zu lesen. In Java werden zu 90% Referenzen uebergeben (bis auf die Primitiven). Komischer weise wird das ganz einfach ueber das Interface der Klasse geloest.
und das macht 0 sinn. was wird in java bezüglich const correctness bitte über das interface gelöst?
PS:
in java hat man in manchen situationen eine primitive form der const correctness wenn es mal nötig wird. wenn man einen privaten member von aussen zugänglich machen will, dann braucht man eine kopie oder man bricht die sicherheit der klasse. in c++ hätte man hier einfach ein const T& zurückgegeben und gut ist, da es ein const in java nicht gibt, muss man kopieren.kommt nicht oft vor, aber es kommt vor.
PS2:
genau aus diesem grund gibt es in java vermehrt immutable objekte. diese sind ja quasi konstant. ich kann zB problemlos ein immutable object nach aussen exposen ohne es kopieren zu müssen.