On 21 Jul., =D6=F6 Tiib wrote:
const member function can not modify any data members of object but
the ones marked explicitily as always 'mutable' (such are rare), nor
can it call other non-const member functions of it nor can it call the
non-const member functions of its data members.
Compiler can take advantage even of unmodified mutable things staying
immutable in the frame where compiler wants to optimize something. Do
not underestimate compiler writers. These are clever guys. 'const' is
there for to help programmers and optimizations are lesser concern.
Right. Making objects const does not mean that the compiler is allowed
to cache the returned value of member functions, neither in C++ nor in
Java. Most compilers will optimize away const variables whose value is
known at compile time (so that we can replace #defines by const
variables), btu that is only a very weak optimization. Any caching of
method calls must be provided by the programmer.
Protection can be circumvented by const_cast. One using it has likely
to prove to his comrades that it was least evil thing in situation he
was in to do. That will be hard to prove to better of peers since C++
is extremely flexible.
That leaves only state pointed at by raw pointer members in class that
stay mutable. I already told why it is so, such raw pointer may point
at something that is not part of the state of class. OTOH i have also
seen policies that declare raw pointers as 'not C++' and forbid usage
of raw pointers. Smart pointers however may keep and enforce constness
as transitive depending on type of relation whose abstraction they
are.
C++ offers the means to extend the const correctness even over
pointers:
class SomeClass
{
public:
void foo () const {}
void bar () {}
};
class AnotherClass
{
protected:
SomeClass* SomeObject;
public:
AnotherClass (SomeClass* Object)
: SomeObject (Object)
{}
SomeClass* GetObject ()
{
return SomeObject;
}
const SomeClass* GetObject () const
{
return SomeObject;
}
};
int main ()
{
SomeClass a;
const AnotherClass b (&a);
b.GetObject ()->foo (); // OK
b.GetObject ()->bar (); // Compilation error: b is const
AnotherClass c (&a);
c.GetObject ()->foo (); // OK
c.GetObject ()->bar (); // OK: c is not const
}
Stroustrup mentiones this technique in his book (can't cite the page
since I seem to haave mislaid it). Although it's a pain in the neck to
write const-overloaded accessors for member pointers, this is a
technique that can extend const-correctness so that it works for
everything.
Yes, this is obvious. Only problem of it is that *SomeObject is not
so may be modified by mistake there. Special smart pointer that