A word of warning at the beginning: This post is about C++ and not about C! So whatever you read here may not necessarily apply to C. Nevertheless you may have a look Sugih’s page which features are in C. Besides I’m not going to explain what references and pointers are.
While working on the KIARA project writing C++11 code I was faced with the task of passing variables to functions which will not alter these. Or pure getter methods. And after reading a post about C++ constness I was left with more questions than really understanding. A quick search revealed thorough FAQ about const usage in C++. Here I’d like to make a short round-up of it.
How to read
First of all, read it from right-to-left. For instance
int const* const p would be read as “p is a constant pointer to a constant int”.
A few examples
string const& s
Let’s say you read something like this:
void MyClass::func (std::string const& s);
So reading from right-to-left this would say “s is reference to a constant std::string”. This implies that
func is not going to modify
s. But keep in mind that you may have a dangling reference here, especially if you work with multi-threaded code. If this would be a pointer instead of a reference it is still possible the pointer to be NULL.
string* const s
void MyClass::func (std::string* const s);
Again, read from right-to-left: “s is a constant pointer to a string”.
s may be modified (the object itself) but
s may not point to a different object. As you may have already noticed it’s not that hard to read when you stick to the “read from right-to-left” rule.
string const* const s
void MyClass::func (std::string const* const s);
This would read “s is a constant pointer to a constant string” and therefore the function guarantees (respectively the compiler enforces it) that the content of
s may not be changed nor may
s point to a different object.
Obviously some signatures mean the same thing:
void MyClass::func (const std::string& s); // you may know this from C void MyClass::func (std::string const& s); void MyClass::func (const std::string* s); void MyClass::func (std::string const* s); // equivalent void MyClass::func (std::string* const s); // Pitfall: NOT equivalent
Now, it doesn’t matter which version you use but is more a decision you have to make. If previously written code opts for one variant you should for the sake of consistency use the same way.
Methods that do not change its object
When you write a pure getter method you may want to tell your compiler that the following code may not change the object itself.
std::string const& MyClass::func () const;
The last const indicates that this function may not alter its objects data.
C++ is not a language you master in a few hours of training, C++ is like meditating and takes daily training.