04 августа 2007

mutable

Интересно, почему не все понимают смысл и полезность ключевого слова mutable. Истинная его ценность состоит в том, чтобы дать возможность в const member-функциях производить такие изменения в объекте, которые не видны снаружи. Все, что видно "снаружи" пользователям объекта - это то, что можно получить через публичный интерфейс. Это нужно для кэширования и ленивых вычислений.

Например, мы пишем адаптер, позволяющий приводить строки типа const char* и std::string к единому интерфейсу вида Data, Size. Для const char* размер можно расчитать через strlen() сразу (не важно, потребуется нам результат вычислений или нет), но можно сделать это только если понадобится:
class StringAdapter
{
public:
explicit StringAdapter(const std::string& String) :
_Data(String.data()), _Size(String.size()), _SizeCached(true) {}

explicit StringAdapter(const char* String) :
_Data(String), _SizeCached(false) {}

const char* Data() const { return _Data; }

size_t Size() const
{
if (!_SizeCached) { _Size = strlen(_Data); _SizeCached = true; }
return _Size;
}

private:
const char* _Data;
mutable size_t _Size;
mutable bool _SizeCached;
};
Без mutable мы бы не смогли внутри Size(), объявленной как const, модифицировать наш кэш.

Комментариев нет: