Over the last two weeks, I have mentioned const
a couple of times.
const
is an often used keyword in C++ (though I would like to see people use it even more), and the different uses can be confusing. In this post I will try to summarize the most common uses:
Constant variables
Constant variables are simple, they cannot be changed after initialization:
const int answer = 43; //Cannot be changed (even though I know you want to) answer = 42; //Nope, not today.
Constant pointers
Constant pointers are a bit more involved, as the pointer can either be constant itself, point to something constant, or both, or none:
int x = 1; const int c = 43; const int * p1 = &c; //Non-const pointer to something const p1 = &x; //So we can change what it points to //(Also note that a pointer to const can point to something non-const). int * const p2 = &x; //Const pointer to something non-const. p2 = c; //Not allowed, cannot change what it points to *p2 = 2; //But can change the thing it points to int * p3 = &c; //Cannot point to something const with a pointer to non-const int * const p4 = &c; //Not even with a const pointer const int * const p5 = &x; //Const ponter to something const p5 = &c; //Cannot change what it points to *p5 = 2; //Cannot change the thing it points to either //And just to confuse things, it doesn't matter on which side of the type you put const, so the following are both a non-const pointer to a const int: const int * d = &c; int const * e = &c; *d = 42; //Not allowed *e = 42; //Not allowed
Const and functions
const
can also be used with functions:
//Passing arguments as reference to const is a best practice, since this allows //you to avoid copying, and still promise the caller that his object won't //be modified. void f(const string& s);
But there is one more use with const
and functions, that is const
member functions. Here, const
applies to the method itself, not the parameters. A const
member function promises to not modify the object on which it is called:
struct Foo { int getFoo() const; //Will not modify the object on which it is called int getMore(); //Might change the object on which it is called }; int doFoo(const Foo& foo) { foo.getFoo(); //Ok foo.getMore(); //Not ok, cannot call non-const methods on const objects }
Functions can also return const
variables and pointers, but I’ll cover that in a follow-up where I’ll also cover operators. (Operators are in essence functions, but there is more to say about them.)
One way that is easier to remember is to read from right-hand side and move to left. E.g. for:
const int * const p5 = &x;
I could be understood like this:
p5 is a constant pointer that points to an int that is constant :)