Skip to content

← Const Correctness and Class Design step 1 of 3

Easy Primitives

The accessor that will not let you look

A const on a member function goes after the parameter list, and it says one thing:

int value() const;    // calling this will not modify the object

It is not a hint. Inside such a function every member is const, so an assignment to one does not compile — and outside it, a const Reading& will only let you call the members that made the promise.

Why this shows up as somebody else’s build error

const propagates outward. The moment one function takes its argument by const& — which every function that only reads should — everything it calls on that argument must be const too, and so on down. Get one accessor wrong deep in a class and the error surfaces in a caller three layers away that has done nothing wrong.

That is the mechanism working, not failing. The alternative is a codebase where nothing is const, every function is free to modify its arguments, and the compiler has no opinion about any of it.

So the rule is worth stating as a habit rather than a fix:

Mark every member function const that does not modify the object, when you write it. Retrofitting const to a class is a long afternoon; adding it as you go costs nothing.

What const does and does not cover

const protects the object’s own bytes. It does not follow a pointer:

class View {
    int* data_;
public:
    void write(int v) const { *data_ = v; }   // compiles!
};

const made data_ a int* const — a pointer you may not reseat — and said nothing about what it points at. This is why a class holding raw pointers gets no real help from const, and one holding its data by value gets a lot.

mutable, for the one honest exception

mutable int cached_total_;   // may change even in a const member function

mutable exists for members that are not part of the object’s observable state: a memoised result, a lock, a hit counter. const is a promise about what callers can observe, not about which bytes move. Use it for caches; do not use it to make an inconvenient error go away.

Your task

This starter does not compile, and the error is the lesson.

summarise takes const std::vector<Reading>&, which is correct — it only reads. Reading‘s accessors do not say they only read, so it cannot call them.

Fix Reading. Do not change summarise or report.

Not every member should get a const: one of the three genuinely modifies the object, and marking that one will produce a second error telling you so.