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, soconst
is 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:
const
function: can be called on any type of object.- Non-
const
function: can only be called by non-const
objects.
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.)