const teilt dem Compiler mit, dass eine Variable unveränderlich ist (nicht nach der Initialisierung geändert werden kann). Es wird verwendet, um konstante Variablen zu deklarieren und für Methoden, die garantiert den Zustand des Objekts nicht ändern.
mutable erlaubt es, den Wert eines Klassenfeldes sogar in const-Methoden zu ändern.
volatile informiert den Compiler, dass der Wert einer Variable irgendwo außerhalb der Kontrolle des Programms (z.B. durch Hardware) geändert werden kann, und der Compiler sollte den Zugriff darauf nicht optimieren.
class Logger { public: void log() const { ++count; // Erlaubt – count ist mutable } private: mutable int count = 0; }; volatile int flag; void wait() { while (flag == 0) { /* Der Compiler optimiert die Schleife nicht, da flag volatile ist */ } }
„Was passiert, wenn ein Klassenmitglied gleichzeitig als
constundmutabledeklariert wird?“
Antwort: Das ist nicht möglich, es sind gegenseitig ausschließende Qualifizierer; der Compiler gibt einen Fehler aus.
Geschichte
In industrieller Software, die mit Hardware arbeitet, hat der Entwickler Daten, die durch externe Interrupts aktualisiert wurden, als normale int deklariert. Die Optimierung des Compilers entfernte wiederholte Leseoperationen dieser Variablen, was dazu führte, dass das Programm in einer Endlosschleife "hängenblieb". Das Problem konnte nur diagnostiziert werden, nachdem es auf
volatile intgeändert wurde.
Geschichte
Eine der Protokollierungsklassen hatte eine Methode
log() const, bei der der Zähler für Aufrufe aktualisiert werden musste. Zunächst wurde dies über denconst_cast-Zeiger gemacht, was viele Warnungen und nicht offensichtliche Bugs verursachte. Das Problem verschwand nach der richtigen Deklaration des Zählers mitmutable.
Geschichte
_Einige Methoden der Klasse wurden als
constdeklariert, aber Mitglieder vom Typ Zeiger wurden geändert (z.B. zur Implementierung von Caching). Dies führte zu einem Verstoß gegen die Logik der "const-correctness" und sogar UB, wenn das Objekt tatsächlich im schreibgeschützten Bereich platziert wurde. Es wäre notwendig gewesen,mutablezu verwenden oder das Design zu ändern.