Как сохранить этот const-правильный, не обманывая компилятор? - PullRequest
3 голосов
/ 17 декабря 2011

У меня есть такой класс 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 () не является constДаже если он изменяет только изменяемые члены данных, компилятор не допустит этого.Вот только два решения, о которых я могу подумать:

  • Загрузка данных в конструктор класса, однако я не хочу этого делать, поскольку ленивая загрузка всего делает приложение быстрее.

  • Make lazilyLoadSomeData() const.Это сработало бы, поскольку изменяло только изменяемые члены, но оно не казалось правильным, поскольку, исходя из названия, метод явно загружает что-то и вносит определенные изменения.

Любойпредложение о том, что было бы правильным способом справиться с этим, без необходимости обманывать компилятор (или вообще отказаться от const-правильности)?

Ответы [ 3 ]

4 голосов
/ 17 декабря 2011

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

3 голосов
/ 17 декабря 2011

Я бы перенаправил вызов прокси-объекту, который является 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;
};
1 голос
/ 17 декабря 2011

Сделать lazilyLoadSomeData () const. Это сработает, поскольку изменяет только изменяемые члены, но кажется, что оно неверно, поскольку, исходя из названия, метод явно загружает что-то и вносит определенные изменения.

Нет, он не вносит некоторые изменения, по крайней мере, с точки зрения того, кто бы ни вызвал getSomeProperty. Все изменения, если вы все делаете правильно, являются чисто внутренними и никак не видны извне. Это решение, которое я бы выбрал.

...