Как сохранить этот const-правильный, не обманывая компилятор?
У меня есть такой класс C++:
class Example {
public:
int getSomeProperty(int id) const;
private:
lazilyLoadSomeData();
}
В принципе getSomeProperty()
вернуть некоторые данные, которые были загружены с помощью lazilyLoadSomeData()
, Поскольку я не хочу загружать эти данные до тех пор, пока они не понадобятся, я вызываю этот метод в getSomeProperty()
int Example::getSomeProperty(int id) const {
lazilyLoadSomeData(); // Now the data is loaded
return loadedData[id];
}
Это не работает, поскольку lazilyLoadSomeData() не является константой. Даже если он изменяет только изменяемые члены данных, компилятор не допустит этого. Я могу придумать только два решения:
Загружать данные в конструктор класса, однако я не хочу этого делать, так как ленивая загрузка всего делает приложение быстрее.
Делать
lazilyLoadSomeData()
Уст. Это сработает, поскольку изменяет только изменяемые члены, но кажется, что это неверно, поскольку, исходя из названия, метод явно загружает что-то и явно вносит некоторые изменения.
Любое предложение о том, что было бы правильным способом справиться с этим, без необходимости обманывать компилятор (или вообще отказаться от const -корректности)?
3 ответа
Я бы перенаправил вызов прокси-объекту, который является mutable
член этого класса, что-то вроде этого:
class Example {
public:
int getSomeProperty(int id) const
{
m_proxy.LazyLoad();
return m_proxy.getProperty(id);
}
private:
struct LazilyLoadableData
{
int GetProperty(int id) const;
void LazyLoad();
};
mutable LazilyLoadableData m_proxy;
};
Вы можете сделать объект-член прокси, который вы объявляете mutable
и который заключает в себе политику отложенной загрузки. Этот прокси сам может быть использован из вашего const
функция. В качестве бонуса вы, вероятно, получите код многократного использования.
Сделайте lazilyLoadSomeData() const. Это сработает, поскольку изменяет только изменяемые члены, но кажется, что это неверно, поскольку, исходя из названия, метод явно загружает что-то и явно вносит некоторые изменения.
Нет, он не вносит некоторые изменения, по крайней мере, с точки зрения того, кто вызвал getSomeProperty. Все изменения, если вы все делаете правильно, являются чисто внутренними и не видны каким-либо образом извне. Это решение я бы выбрал.