I understand that the function is not allowed to change the state of the object, but I thought I read somewhere that the compiler was allowed to assume that if the function was called with the same arguments, it would return the same value and thus could reuse a cached value if it was available. e.g.
class object
{
int get_value(int n) const
{
...
}
...
object x;
int a = x.get_value(1);
...
int b = x.get_value(1);
then the compiler could optimize the second call away and either use the value in a register or simply do b = a;
Is this true?
To make a member function constant, the keyword “const” is appended to the function prototype and also to the function definition header. Like member functions and member function arguments, the objects of a class can also be declared as const.
Explanation: The constant member functions are a special type of member functions. These are intended to restrict any modification in to the values of object which is used to invoke that function. This is done to ensure that there are no accidental modifications to the object. 2.
A "const function", denoted with the keyword const after a function declaration, makes it a compiler error for this class function to change a member variable of the class. However, reading of a class variables is okay inside of the function, but writing inside of this function will generate a compiler error.
The const qualifier at the end of a member function declaration indicates that the function can be called on objects which are themselves const. const member functions promise not to change the state of any non-mutable data members.
const
is about program semantics and not about implementation details. You should mark a member function const
when it does not change the visible state of the object, and should be callable on an object that is itself const
. Within a const
member function on a class X
, the type of this
is X const *
: pointer to constant X
object. Thus all member variables are effectively const
within that member function (except mutable
ones). If you have a const
object, you can only call const
member functions on it.
You can use mutable
to indicate that a member variable may change even within a const
member function. This is typically used to identify variables used for caching results, or for variables that don't affect the actual observable state such as mutexes (you still need to lock the mutex in the const
member functions) or use counters.
class X
{
int data;
mutable boost::mutex m;
public:
void set_data(int i)
{
boost::lock_guard<boost::mutex> lk(m);
data=i;
}
int get_data() const // we want to be able to get the data on a const object
{
boost::lock_guard<boost::mutex> lk(m); // this requires m to be non-const
return data;
}
};
If you hold the data by pointer rather than directly (including smart pointers such as std::auto_ptr
or boost::shared_ptr
) then the pointer becomes const
in a const
member function, but not the pointed-to data, so you can modify the pointed-to data.
As for caching: in general the compiler cannot do this because the state might change between calls (especially in my multi-threaded example with the mutex). However, if the definition is inline then the compiler can pull the code into the calling function and optimize what it can see there. This might result in the function effectively only being called once.
The next version of the C++ Standard (C++0x) will have a new keyword constexpr
. Functions tagged constexpr
return a constant value, so the results can be cached. There are limits on what you can do in such a function (in order that the compiler can verify this fact).
The keyword mutable on member variables allows for const functions to alter the state of the object at hand.
And no, it doesn't cache data (at least not all calls) since the following code is a valid const function that changes over time:
int something() const { return m_pSomeObject->NextValue(); }
Note that the pointer can be const, though the object pointed to is not const, therefore the call to NextValue on SomeObject may or may not alter it's own internal state. This causes the function something to return different values each time it's called.
However, I can't answer how the compiler works with const methods. I have heard that it can optimize certain things, though I'd have to look it up to be certain.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With