С++ для начинающих



         

Объявление mutable


При объявлении объекта класса Screen константным возникают некоторые проблемы. Предполагается, что после инициализации объекта Screen, его содержимое уже нельзя изменять. Но это не должно мешать нам читать содержимое экрана. Рассмотрим следующий константный объект класса Screen:

const Screen cs ( 5, 5 );

Если мы хотим прочитать символ, находящийся в позиции (3,4), то попробуем сделать так:

// прочитать содержимое экрана в позиции (3,4)

// Увы! Это не работает

cs.move( 3, 4 );

char ch = cs.get();

Но такая конструкция не работает: move()– это не константная функция-член, и сделать ее таковой непросто. Определение move() выглядит следующим образом:

inline void Screen::move( int r, int c )

{

   if ( checkRange( r, c ) )

   {

      int row = (r-1) * _width;

      _cursor = row + c - 1;      // модифицирует _cursor

   }

}

Обратите внимание, что move()изменяет член класса _cursor, следовательно, не может быть объявлена константной.

Но почему нельзя модифицировать _cursor для константного объекта класса Screen? Ведь _cursor – это просто индекс. Изменяя его, мы не модифицируем содержимое экрана, а лишь пытаемся установить позицию внутри него. Модификация _cursor должна быть разрешена несмотря на то, что у класса Screen есть спецификатор const.

Чтобы разрешить модификацию члена класса, принадлежащего константному объекту, объявим его изменчивым (mutable). Член с таким спецификатором не бывает константным, даже если он член константного объекта. Его можно обновлять, в том числе функцией-членом со спецификатором const. Объявлению изменчивого члена класса должно предшествовать ключевое слово mutable:

class Screen {

public:

   // функции-члены

private:

   string                     _screen;

   mutable string::size_type  _cursor; // изменчивый член

   short                       _height;

   short                       _width;

};

Теперь любая константная функция способна модифицировать _cursor, и move() может быть объявлена константной. Хотя move() изменяет данный член, компилятор не считает это ошибкой.




Содержание  Назад  Вперед