C++ - const
const keyword declares an object as constant, i.e. once initialized, the value won't change.
Read-only, but not Immutable or always the same
A const object is read-only but this does not imply that it is immutable nor does it imply that the value is always the same.
void f(const std::string& s) {
const int size = s.size();
// ...
}
f(""); // size = 0
f("foo"); // size = 3
Other ways to change a const: mutable keyword and const_cast.
What does const apply to?
TL;DR: const applies to the thing left of it, if there's nothing on the left, then it applies to the thing right of it
const int*: nothing on the left, soconstis forint: a pointer to a constant integer. equivalent toint const *.int* const: a constant pointer to an integer, the pointer cannot point to other address, the content can be changed.const int* const: a constant pointer to a constant integer, both content and the address are read-only, equivalent toint const* const.int const* const*: a pointer to a const pointer to a constant integer.int const* const* const: a constant pointer to a constnat pointer to a constant integer.
Where to use const?
const object
const int kMax = 100;
- needs to be initialized at the time of declaration.
- attempt to change the data member of const objects results in a compile-time error.
const member function
class Foo {
// ...
int get_data() const;
}
const member function: not allowed to modify the object.
Compare:
constfunction: can be called on any type of object.- Non-
constfunction: can only be called by non-constobjects.
Note that const means the function does not modify the states of this object, not "read only", for example if a function writes to a database and it does not change the states, it can be const.
class Foo {
// ...
absl::Status InsertOrUpdateBarTable() const {
// ... does not change state of Foo.
}
}
Function parameters
The const in front of the function parameter indicates that it does not intend to change the states in foo:
void f(const Foo& foo) {
// ...
}
Best Practices
Prefer const member functions
Make as many functions const as possible so that accidental changes to objects are avoided.
Top-level const
Top-level const on function parameters in declarations that are not definitions is meaningless and ignored by the compiler.
There's very little point in returning a value with top-level const in C++. It's the callers responsibility to decide if they want to mutate the value they obtain from the function or not.
void F(const int x); // 1: declares F(int)
void F(int* const x); // 2: declares F(int*)
void F(const int* const x); // 3: declares F(const int*)
Avoid returning const values
Returning const for values (not references) disables a lot of optimisations and usually causes unnecessary copies. When returning values from functions, avoid marking the type const. (That is, no const T, although const T& and const T* are perfectly fine.)