Рассмотрим следующий пример:
#include <iostream>
using std::endl;
using std::cout;
class my_class {
private:
int _expensive_count_operation() const {
return 10;
}
bool cached;
int last_count;
public:
my_class() { cached = false; }
int get_count() {
if (cached) {
cout << "Got count from cache." << endl;
return last_count;
}
cout << "Computing count." << endl;
last_count = _expensive_count_operation();
cached = true;
return last_count;
}
int get_const_count() const {
my_class* _this = const_cast<my_class*>(this);
if (cached) {
cout << "Got count from cache." << endl;
return last_count;
}
cout << "Computing count." << endl;
_this->last_count = _expensive_count_operation();
_this->cached = true;
return last_count;
}
};
int main() {
my_class my_object1,my_object2;
int count;
count = my_object1.get_count();
cout << "Count: " << count << endl;
count = my_object1.get_count();
cout << "Count: " << count << endl;
count = my_object2.get_const_count();
cout << "Count: " << count << endl;
count = my_object2.get_const_count();
cout << "Count: " << count << endl;
}
Использование const_cast в методе get_const_count позволяет вам сохранить метод const. Теперь вопрос в том, какие опасности связаны с этим? И как они соотносятся с опасностями, связанными с потерей способности использовать экземпляры const (или указатели на них) этого класса? И даже лучше, есть ли лучший подход?
Я часто оказываюсь в такой ситуации, когда пишу код, который затем хочу оптимизировать с помощью кэширования. Проблема заключается в том, что мне нужно удалить объявления const и распространить эти изменения в остальной части кода.
Я бы предпочел отметить все атрибуты, связанные с кэшем, как mutable
, Значение const
должно быть, что наблюдаемые состояния не затрагиваются этими методами (что в любом случае должен делать ваш кеш). Имейте в виду, что все const-методы также должны быть поточно-ориентированными.
Для дальнейшей информации я рекомендую блог Херб Саттер — он написал кое-что о const-правильности начиная с c ++ 11. Здесь также Прямая ссылка на похожее видео от Херб.
ТОЛЬКО действительно для использования const_cast
удалять const
если оригинальный объект не был const
, Если это всегда так, это не должно быть проблемой, чтобы сделать это.
Хотя я бы предпочел установить last_count
а также cached
в mutable
… Потому что вы действительно не хотите случайно изменять какие-либо другие части объекта — но вы действительно хотите изменить те в const
функция-член.