Ken Katagiri
Ken Katagiri

Reputation: 317

Why Do We Need const methods?

class function const is used to tell the compiler that a class function will not change a member variable. Thus, a constant object of that type can safely call it. Below is a simple example.

#include <iostream>
using namespace std;

class X {
private:
  int a{1};

public:
  void PrintA() const {
    cout << a << "\n";
  }
};

int main() {
  const X x;
  x.PrintA();
}

We tell the compiler that #PrintA is const, so constant objects can safely call it. However, it seems that the compiler is actually smart enough to detect that a function is read-only or not, independent of the const keyword. If I add an a=10 in the above code like so

#include <iostream>
using namespace std;

class X {
private:
  int a{1};

public:
  void PrintA() const {
    cout << a << "\n";
    a = 10;
  }
};

int main() {
  const X x;
  x.PrintA();
}

I get

exp.cpp: In member function ‘void X::PrintA() const’:
exp.cpp:11:9: error: assignment of member ‘X::a’ in read-only object
     a = 10;

In other words, the const key-word can't trick the compiler into allowing the mutation of a constant object. So my question is, why do developers need to declare a method const? It seems like, even without that hint, the compiler distinguishes read-only and non-read-only methods, so can properly catch cases of attempts to mutate constant objects.

Upvotes: 0

Views: 801

Answers (2)

TheUndeadFish
TheUndeadFish

Reputation: 8171

the compiler distinguishes read-only and non-read-only methods

First consider how easily the compiler can do this with the const designation as it exists today.

  • To determine if the implementation of PrintA obeys the rules, the compiler only needs to look at that implementation.
  • To determine if x.PrintA(); is valid for const X x; it only needs the declaration of PrintA.

Now imagine if we didn't have function-level const

  • To determine if the implementation of PrintA obeys the rules, the compiler has to determine if it's not acting read-only and then scan across your entire program to find if it ever gets called on a const object.

I'm sure that would massively bloat the link time of large programs.

But then a significant concern are virtual functions. Imagine one derived class overrides with a read-only implementation, but then a different derived class overrides with a non-read-only implementation. Then if such a method is called on a const object, what is the compiler to do since it may not be able to determine at compile-time which implementation is going to be called? Would we just have to rule out virtuals from ever being possible to call on const objects? That would be unfortunately limiting.

Furthermore, this idea wouldn't work when callers vs implementations are separated across DLL boundaries (even for non-virtual functions), since those are only connected together at run-time.

So overall it just seems more difficult/problematic for us the have the ability to declare const objects if we were to leave it to the compiler to have to figure out if methods are implemented in a const way or not.

Upvotes: 2

Chris Dodd
Chris Dodd

Reputation: 126203

It's not a hint -- it's part of the interface of the method. If you remove the const, the error in PrintA will go away and you'll get an error in main instead. You need const for the same reason you need public and private -- to define the interface you want. The compiler will then check to make sure you don't violate that interface you've declared.

Upvotes: 4

Related Questions