Use const
identifiers by default. They provide guarantees for the reader/maintainer, and are way easier to build in than to insert afterwards.
Both member variables and methods would be declared const
, as well as function arguments. const
member variables enforce proper use of the initializer list.
A side-effect of this rule: avoid methods with side-effects.
------ EDIT
const
member variables seemed like a good idea; this is not always the case: they effectively make any object immutable. This becomes problematic for e.g. sorting a vector.
struct A {
const int i;
};
bool operator<(const A& lhs, const A& rhs) {
return lhs.i < rhs.i;
}
int main() {
std::vector<A> as;
as.emplace_back(A{1});
std::sort(begin(as), end(as));
}
error message:
... note: copy assignment operator of 'A' is implicitly deleted because
field 'i' is of const-qualified type 'const int'
...
in instantiation of function template specialization 'std::sort<...>'
requested here
std::sort(begin(as), end(as));