If you miss the first const, one simple typo can make it wrong:
1 2
Rational a, b, c; if (a * b = c)
In the code above, I know you want to type == not =. But compiler will happily generate code for you, and maybe you have to spend hours to debug. All you need to do is use const to prevent unwanted behavior.
And then to illustrate how const member function works:
1 2 3 4 5 6
TextBlock nonConstObj("Hello"); const TextBlock constObj("Hello"); std::cout << nonConstObj[0]; // call const member function std::cout << constObj[0]; // call const member function nonConstObj[0] = 'J'; // fine constObj[0] = 'J'; // error!
Typically corresponding const and non-const member functions are very similar, to avoid code duplication, we make non-const member function call const member function with certain cast:
As you can see, the code has two casts, not one. We want the non-const operator[] to call the const one, but if, inside the non-const operator[], we just call operator[], we’ll recursively call ourselves. So we cast *this from TextBlock& to const TextBlock&. The static_cast is to remove the const from the const operator[]‘s return value.