TITLE: Const objects and caching values PROBLEM: caspers@fwi.uva.nl (John Caspers) Coplien (Advanced C++ Programming Styles & Idioms) writes the following code on pages 60 and 61: [ I squished it a bit ] class String { public: String( const String& s ) { s.rep->count++; // ... } // ... private: StringRep *rep; }; class StringRep { friend String; private: // ... char *rep; int count; }; The question is: in String's copy ctor, the argument 's' is const. But the statement 's.rep->count++' changes the state of the StringRep object s.rep is pointing to... Any comments on this? My compiler (BC++ 3.1) didn't complain about changing an object pointed to by a member of a const object. Should it? RESPONSE: jbuck@forney.berkeley.edu (Joe Buck), 7 Oct 92 The code above is perfectly valid. That is correct. For a pointer, either the pointer itself can be constant, or the pointer can point to constant storage, or both. That is, we could have 1. StringRep *pointerToRep; 2. const StringRep *pointerToConstRep; 3. StringRep * const constPointerToRep; 4. const StringRep * const constPointerToConstRep; Within a const String, the pointer to the StringRep becomes type 3: the pointer itself is const, but the StringRep pointed to is NOT const. We have effectively put the String object, but NOT the thing pointed to by the String object, in a ROM. Just as ROMs can contain pointers to RAM, so can a const object have pointers to non-const storage. Your compiler should (must!) not complain. It is because this issue is so widely misunderstood that you see so much "cast away const" code that the ANSI committee seems to feel obliged to bless it. The above technique permits const objects to have a cache that is updated by const methods, without casting away const. All serious C++ programmers should understand it thoroughly.