Amarnath Shanbhag
Amarnath Shanbhag

Reputation: 159

const member function apparently allows to change state of object

class Foo
{
public:
  Foo(int& cnt) : cnt_(cnt) {}
  void test() const
  {
    cnt_ = 0;
  }

protected:
  int& cnt_;
};

int cnt;
int main()
{
  Foo foo(cnt);
  foo.test();
}

The above code compiles. The test function is const, however we are allowed to change the value of cnt_. If "cnt_" is not a reference then compiler gives an error as expected. However if "cnt_" is a reference like above, why doesn't compiler give an error ? We are still changing the state of the object "Foo" inside a const member function, isn't it ?

Upvotes: 1

Views: 42

Answers (2)

jfMR
jfMR

Reputation: 24738

The member cnt_, declared as:

int& cnt_;

is a reference, and inside the member function:

void test() const;

the const-qualification is applied to the members, i.e.: the reference, and not to the object referenced. Therefore, the object being referenced can still be modified through that reference, even inside a const member function, like the one above.

Note that, references can't be assigned after initialization anyway, so it really doesn't change what you can do with that reference.

Upvotes: 1

R Sahu
R Sahu

Reputation: 206567

Perhaps a pointer analogy will help.

Let's say you have:

struct Foo
{
   Foo(int* cnt) : cnt_(cnt) {}

   void test1() const
   {
      *cnt_ = 0;
   }

   void test2(int* p) const
   {
      cnt_ = p; // Not allowed
   }

   int* cnt_;
};

In test1, you are not changing cnt_. You are changing the value of cnt_ points to. That is allowed.

In test2, you are changing cnt_. That is not allowed.

In your case, you are not changing cnt_ to reference another object. You are changing the value of the object cnt_ references. Hence, it is allowed.

Upvotes: 0

Related Questions