const
о семантике программы, а не о деталях реализации. Вы должны пометить функцию-член const
, когда она не изменит видимое состояние объекта и должна быть вызвана для объекта, который сам является const
. В функции члена const
класса X
тип this
: X const *
: указатель на постоянный X
объект. Таким образом, все переменные-члены фактически составляют const
внутри этой функции-члена (кроме mutable
). Если у вас есть объект const
, вы можете только называть его функциями const
.
Вы можете использовать mutable
, чтобы указать, что переменная-член может меняться даже в пределах функции-члена const
. Обычно это используется для идентификации переменных, используемых для результатов кеширования, или для переменных, которые не влияют на фактическое наблюдаемое состояние, такое как мьютексы (вам все равно необходимо заблокировать мьютекс в функциях-членах const
) или использовать счетчики.
class X
{
int data;
mutable boost::mutex m;
public:
void set_data(int i)
{
boost::lock_guard<boost::mutex> lk(m);
data=i;
}
int get_data() const // we want to be able to get the data on a const object
{
boost::lock_guard<boost::mutex> lk(m); // this requires m to be non-const
return data;
}
};
Если удерживать данные по указателю, а не непосредственно (в том числе смарт-указатели, такие как std::auto_ptr
или boost::shared_ptr
), то указатель становится const
в функции в const
члена, но не заостренный к данным, так что вы можете изменять заостренные данные.
Что касается кэширования: в общем случае компилятор не может этого сделать, потому что состояние может меняться между вызовами (особенно в моем многопоточном примере с мьютексом). Однако, если определение является встроенным, компилятор может вывести код в вызывающую функцию и оптимизировать то, что он видит там. Это может привести к тому, что функция эффективно только вызывается один раз.
Следующая версия C++ Standard (C++0x) будет иметь новое ключевое слово constexpr
. Функции, помеченные constexpr
, возвращают постоянное значение, поэтому результаты могут быть кэшированы. Существуют ограничения на то, что вы можете сделать в такой функции (чтобы компилятор смог проверить этот факт).
На самом деле, если у вас есть член помеченных изменчивый, то константная функция все еще может изменить Это. Это в основном полезно для кэширования последнего результата. :-) – 0124816 2008-09-19 05:29:53