pumuckl schrieb:
hustbaer schrieb:
const bedeutet ja nicht dass der Zustand des Objekts nicht geändert werden darf. Es gibt ja schliesslich mutable
Jein. Mutable Member gehören nicht zum Zustand der Klasse. Und const_cast bei konstanten Objekten ist böse. Ist Sache des Standpunkts des Betrachters. Von der Programmlogik her heißt const "nicht anfassen". Aus Compilersicht kann man const wegcasten und schauen was passiert, wenn man sich Mühe gibt frisst der Compiler fast alles...
Ich weiss schon was du meinst. Ich meinte bloss: der C++ Standard liefert zwar viele deutliche Hinweise darauf, wie const zu verwenden ist... (die Semantik bei eingebauten Typen sowie Typen der Standard-Library, das Keyword heisst "const" und nicht "foo" oder sonstwie). Dennoch schreibt er keine genaue Interpretation/Bedeutung für UDTs vor.
Wenn ich möchte, bastle ich mir eine Klasse für einen Kartenstabel (Spielkarten), und definiere "const" dann so, dass man zwar Karten abheben kann, den Stapel aber nicht mischen. Oder ich mache eine Stream-Klasse, aus der man zwar über const lesen kann (und damit den "Stream-Pointer" verschieben, also durchaus den State verändern), aber nix schreiben kann. Oder wozu ich halt grad lustig bin.
Natürlich wäre das mit dem Kartenstapel total plem, aber der Standard sagt nicht dass das verboten oder böse wäre. Das mit dem Stream ist vermutlich auch keine gute Idee, weil man es besser über Interface-Klassen (ReadStream, WriteStream) lösen könnte.
Ich würde es eher so formulieren: man sollte sich bei "const" an das "Principle of least astonishment" denken. (Und nicht nur bei "const")
Und wenn man das tut, dann verbieten sich natürlich diverse exotischere Interpretationen.
Und ich würde auch nicht sagen dass delete den Zustand von irgendwas ändert. Vorher isses da, nachher isses nichtmehr da. Was nichtmehr da ist, kann keinen Zustand haben, also kann sich der Zustand auch nicht geändert haben. Nen?
Exakt. Bei Betreten des Destruktors hat die Lebenszeit des Objektes bereits aufgehört. Damit ist kein Zustand mehr vorhanden und es kann passieren was will. Deshalb gibts auch keine const-Destrutkoren, und in Destruktoren können die Member bei Bedarf doch wieder geändert werden. Gleiches gilt allerdings für den Ctor - die Lebenszeit eines Objektes und damit der Zustand beginnt erst bei Verlassen des Ctors.
Jo. Da sind wir uns ja einig, wenn ich dich richtig verstehe...
(das Objekt kann selbst ja niemals const sein, wenn man es über new erzeugt hat)
Doch, es kann. Während des Aufrufs von new gibts noch kein fertiges Objekt das const sein könnte. Folgendes funktioniert bei mir ohne Beschwerden:
class X
{
int i;
public:
X() : i(5) { i = 6 ;}
~X() { i = 7;}
};
int main()
{
X const* xp = new X();
delete xp;
cout << "Geht doch!" << endl;
}
Er, nein. Denkfehler.
Das Objekt der Klasse X ist hier NICHT const. "new X()" erzeugt das Objekt. Wo ist da ein const? Dass du den Returnwert von "new X()" dann in einem "Zeiger auf const" ablegst ist hier überhaupt nicht relevant. Der Punkt ist: es gibt nicht bloss keine const DEstruktoren, es gibt auch keine const KONstruktoren. Damit kann ein Objekt welches einen Ctor hat NIEMALS wirklich const sein. Genaugenommen nichtmal dann, wenn es global/statisch instanziert wird.
In deinem Beispiel ist bloss der Zeiger auf dein Objekt ein "const-Zeiger". Das bedeutet weiter, dass du in diesem Beispiel das const ohne weiteres wegcasten dürftest, ohne dass es hier zu UB kommen darf.