It works like this:
class List
{
public:
void addItem(int i) { /* do add */ }
void addItem(int i) const { throw new ConstListException(); }
}
List* list = new List();
const List* clist = list;
list.addItem(i); // fine - adds an item
clist.addItem(i); // throws an exception because const version is invoked
IOW, if you define a member function and you don't make it const, then you can't call it using a const ref to the object.
If you define a member function and make it const, you can call it with both a const and non-const ref to the object.
If you define both a non-const and const version of the same function, the const version is called when you have a const ref to the object and the non-const version is called with non-const refs.
As developers aren't particularly good judges on what is const and what isn't const, this "feature" has turned out to be a PITA.
------
There is a different approach that was employed in ObjectiveC.
The collection classes (which is usually the issue anyhow - do you return a new copy or a reference to private data?) are defined at two levels.
NSArray, NSDictionary, and NSSet have read-only semantics. No mutators are defined in these classes. So they are effective immutable. NSMutableArray is a subclass of NSArray and adds mutator methods (those that you wouldn't declare const). Same with NSDictionary and NSSet, mutable subclasses exist.
Suppose I have a class Artist with an array of Paintings.
@interface Artist
{
NSMutableArray* _paintings;
}
-(void)addPainting:(Painting*)p { [_paintings addObject: p]; }
-(void)removePainting:(Painting*)p { [_paintings removeObject: p; }
-(NSArray*)paintings { return _paintings; }
@end
Notice that when asked for the list of paintings, I say I return the superclass type NSArray. Its private data, but if you try to send it a mutator method, the compiler will warn you that this is not cool (but it'll still do it).
Thus, I get out of copying the collection and still keep it from being modified. (They could downcast - but downcasting is evil and thus they deserve what they get for that).
Simple two level design idea. C++'s const mechanism tries to do the same thing, but its more confusing to use and I think it fails because its confusing.