Notes on the C++ const declarator

The term const, which comes from the word constant, is used to limit the ability of code to alter the state of objects.

The state of a variable declared as const can not be altered. For example, the following will not compile.

void main()
{
   const int a = 0;
   a = 1;
}

This is also true for variables that identify instances of classes. For example, the following will not compile.


#include <string>

void main()
{
   const std::string a = "x";
   a[0] = 'y';
}

A variable declared as const that identifies an instance of a class can not be re-assigned to another instance. For example, the following will not compile.

#include <string>

void main()
{
   const std::string a = "x";
   const std::string b = "y";
   a = b;
}

However, the following compiles, because s2 is not const, which means it can be assigned to a different string instance.

#include <string>

void main()
{
   const std::string s1("hi");
   std::string s2("bye");
   s2 = s1;
}

A variable declared as const can not be assigned to a reference not declared as const. For example, the following will not compile.

#include <string>

void main()
{
   const int i = 0;
   int & j = i;
}

However, variable declared as const can be assigned to a reference also declared as const. For example, the following will compile.

#include <string>

void main()
{
   const int i = 0;
   const int & j = i;
}

A const iterator disallows modification of the object to which it refers. Therefore, the following code does not compile.


#include <set>

void main()
{
   std::set<int> s;
   s.insert(0);
   std::set<int>::const_iterator it = s.begin();
   *it = 1;
}

However, a const_iterator can be advanced, so the following code will compile.

#include <set>

void main()
{
   std::set<int> s;
   s.insert(0);
   std::set<int>::const_iterator it = s.begin();
   ++it;
}

However, an iterator declared as const can not be modified to represent another iterator, so the following code will not compile.

#include <set>

void main()
{
   std::set<int> s;
   s.insert(0);
   const std::set<int>::iterator it = s.begin();
   it = s.end();
}

However, we can change the state of an iterator declared as const and we can change the value to which the iterator refers, so the following code will compile.

#include <set>

void main()
{
   std::set<int> s;
   s.insert(0);
   s.insert(1);
   const std::set<int>::iterator it = s.begin();
   ++it;
   *it = 0;
}

A member function declared as const can not change the state of instance of its class. For example, the following code will not compile.

#include <string>

class c
{
public:
   void increment() const { ++i; }

private:
   int i;
};

void main()
{
}

A member function declared as const can not call another member function not declared as const. For example, the following code will not compile.

#include <string>

class c
{
public:
   void increment() { ++i; }
   void addOne() const { increment(); }

private:
   int i;
};

void main()
{
}