Любая попытка модифицировать константный объект из программы обычно помечается компилятором как ошибка. Например:
const char blank = ' ';
blank = '\n'; // ошибка
Однако объект класса, как правило, не модифицируется программой напрямую. Вместо этого вызывается та или иная открытая функция-член. Чтобы не было “покушений” на константность объекта, компилятор должен различать безопасные (те, которые не изменяют объект) и небезопасные (те, которые пытаются это сделать) функции-члены:
const Screen blankScreen;
blankScreen.display(); // читает объект класса
blankScreen.set( '*' ); // ошибка: модифицирует объект класса
Проектировщик класса может указать, какие функции-члены не модифицируют объект, объявив их константными с помощью спецификатора const:
class Screen {
public:
char get() const { return _screen[_cursor]; }
// ...
};
Для класса, объявленного как const, могут быть вызваны только те функции-члены, которые также объявлены со спецификатором const. Ключевое слово const помещается между списком параметров и телом функции-члена. Для константной функции-члена, определенной вне тела класса, это слово должно присутствовать как в объявлении, так и в определении:
class Screen {
public:
bool isEqual( char ch ) const;
// ...
private:
string::size_type _cursor;
string _screen;
// ...
};
bool Screen::isEqual( char ch ) const
{
return ch == _screen[_cursor];
}
Запрещено объявлять константную функцию-член, которая модифицирует члены класса. Например, в следующем упрощенном определении:
class Screen {
public:
int ok() const { return _cursor; }
void error( int ival ) const { _cursor = ival; }
// ...
private:
string::size_type _cursor;
// ...
};
определение функции-члена ok() корректно, так как она не изменяет значения _cursor. В определении же error() значение _cursor изменяется, поэтому такая функция-член не может быть объявлена константной и компилятор выдает сообщение об ошибке: