"Physical" constness comes from declaring an object const
, and could, in principle, be enforced by placing the object in read-only memory, so it cannot change. Attempting to change it will cause undefined behaviour; it might change, or it might not, or it might trigger a protection fault, or it might melt the memory chip.
"Logical" constness comes from declaring a reference or pointer const
, and is enforced by the compiler. The object itself may or may not be "physically" const, but the reference cannot be used to modify it without a cast. If the object is not "physically" const, then C++ allows you to modify it, using const_cast
to circumvent the protection.
A mutable
class member can be modified even if the class object itself (or the reference or pointer used to access it) is const
. Examples of good uses of this are a mutex that must be locked during a read operation, and a cache to store the result of an expensive read operation. In both cases, the operation itself should be a const
function (since it doesn't affect the visible state of the object), but it needs to modify the mutex or the cache, so these need to be mutable
. It can also be abused to make the object visibly change when logically it shouldn't, so use it with care; only declare members mutable
if they don't form part of the externally visible state.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…