I think the answer has already been given with regards to "mutable" and
"const_cast", but at least I seem to have missed at least one reply (sent in
private?) in this discussion. So here are my thoughts :)
Am 24.07.2013 um 09:29 schrieb Mandeep Sandhu <[email protected]>:
> ...
> Also, doesn't a "const" (old sense of the word) member function mean - "I'm
> not going to alter the state of the object" ?
I usually interpret a "const" as "I am not going to alter the state of the
object - as far as YOU (the caller) are concerned, that is."
One canonical example has already been given with the "toLatin1" use case:
"logically" the "state that is important to the caller - and accessible via the
API!" must not (well, "should not") change when a "const" method is called.
However the class might do lazy initialisation and other optimisations like
allocating/updating *internal* cache structures. Those would then be declared
"mutable".
So yes, requesting a "Latin1" representation of a given string does not alter
the actual string, hence "logically" the state of the class does not change and
declaring the toLatin1 method as const is the right thing to do.
> If so, that would make it thread-safe in the special scenario (mentioned by
> OP) where only "reads" are being attempted, right? Can an implementation make
> it thread-unsafe while still being const (again considering only the special
> "read-only" scenario)?
So by now we know that a "const" method can mess around with the "non-public
internal state" as it pleases: allocate memory, write to mutable member
variables etc. - so that makes it still thread-unsafe, even if your threads
would only call the "const" (read) members!
Thiago has already given an example where a "const" method would allocate an
internal (mutable) cache, and if that method would be called from different
threads you might end up with leaked memory (in the best case - you might even
end up with dangling pointers).
Microsoft is giving a "mutable" example with an access counter:
http://msdn.microsoft.com/en-us/library/4h2h0ktk(v=vs.80).aspx
If that increment was not atomically implemented (and to be honest, right now I
don't know whether a "foo++" is atomic - I don't think it is, is it?) and again
two threads would call that method with the "wrong" timing, you might "miss" a
count.
By the way IMHO that example is at least questionable: it is super simple to
understand, but what would you do later on with such a counter? Block the
caller after 1000 calls or return a different result then? Then in my opinion
the "access counter" would be part of the "public logical state" of the class
and hence any method changing that counter should /not/ be declared public!
If on the other hand you would "defragment some internal cache structures every
1000th call" then the "const" would probably be okay.
Bottom line: you walk on a very thin line when breaking the "const" with
"mutable" (or "const_cast"). You can totally mis-use it and render the "const"
completely meaningless, you can now rant about C++ letting you shoot into your
foot (once again) and how "const" does not give you /any/ guarantee about
thread-safety (as long as only "readers" are involved... (even though I
understand that "reader-thread-safety" is now the *intention* of the C++ 11
standard library...)
But think about it: having a loophole such as "mutable" is actually
(ironically?) the only way(1) to make a class thread-safe while still offering
const methods! (Java for instance does not even have the language concept of
"const methods").
Because the other canonical example is declaring mutex variables as "mutable",
because you still need/want to modify the state of a mutex, even in a const
method :)
Cheers,
Oliver
(1) Off course the language could also provide "special mutable mutex
variables" and omit "mutable" etc. - but that would not be less awkward, and
prevent the - rightful - use case of "internal cache modifications"
_______________________________________________
Interest mailing list
[email protected]
http://lists.qt-project.org/mailman/listinfo/interest