Глобальное объявление структуры данных с параметром - PullRequest
0 голосов
/ 11 октября 2018

Я использовал структуру данных LRU в main (), например:

int main()
{
    load_parameter();
    cache::lru_cache<int, float> states_action0(STATES_NO_LRU);
    cache::lru_cache<int, float> states_action1(STATES_NO_LRU);   
    cache::lru_cache<int, float> states_action2(STATES_NO_LRU);
    .........

}

Обратите внимание, что STATES_NO_LRU - переменная целочисленного типа, которая загружается в начале main ().

Однако я хотел бы переместить объявление структуры данных LRU за пределы main (), чтобы объявить его как глобальный тип.

В области глобального объявления STATES_NO_LRU не может быть загружен.Как в этом случае работать с переменной STATES_NO_LRU?Подводя итог, я хотел бы использовать lru_cache в качестве глобальной структуры данных.

Исходный код (часть заголовка) lru_cache выглядит следующим образом

namespace cache {

template<typename key_t, typename value_t> class lru_cache { public:
        typedef typename std::pair<key_t, value_t> key_value_pair_t;
        typedef typename std::list<key_value_pair_t>::iterator list_iterator_t;

        lru_cache(size_t max_size) :
                _max_size(max_size) {
        }

Ответы [ 2 ]

0 голосов
/ 11 октября 2018

В настоящее время, когда ваш объект кеша создается, вы передаете соответствующие аргументы.Это означает, что вам нужно знать, какими должны быть аргументы для его конструктора при создании объектов.C ++ инициализирует объекты со статическим временем жизни в 2 этапа:

  1. Статическая инициализация (приблизительно: константы, известные во время компиляции, например, int var= 42; в области имен)

  2. Динамическая инициализация (приблизительно: некоторый код должен быть запущен для их инициализации, например, int var2 = foo() в области пространства имен)

В сущности, это означает, что вы должны выполнить одно из следующих действий:Несколько вещей:

Создайте ( или инициализируйте ) объект в более позднее время.

Это подход, который я бы порекомендовал вам.На самом деле это два разных решения, одно с указателями, а другое с поздней инициализацией уже созданного объекта, но оба имеют одну и ту же идею, поэтому я объединю их в одну группу.Я исследую только вариант указателя, другой должен быть легким для подражания.

Что бы это значило, это объявить lru_cache как указатель, а не по значению.Позже вы будете динамически создавать объект всякий раз, когда вы загрузите необходимые данные.

Решение Pointer будет выглядеть примерно так:

size_t load_parameter() {
    //do magic;
    return 42;
}

std::unique_ptr<lru_cache<int, float>> states_action0 = nullptr;

int main()
{
    size_t STATES_NO_LRU = load_parameter();
    states_action0 = std::make_unique<lru_cache<int, float>>(STATES_NO_LRU);
}

Решение поздней инициализации будет по умолчанию создавать объект lru_cache и реализовывать метод lru_cache::initialize(size_t maxSize) для инициализации объекта.

Создание фабричной функции, которая будет инициализировать создание объекта.

  1. Если мы не вызвали load_paramter(), вызовите его и сохраните результаты в локальной статической форме.
  2. Создайте lru_cache объект с использованием локальной статики и верните его.

Я бы настоятельно рекомендовал против такого решения.Время, в которое произойдет ваша загрузка, определяется реализацией и, скорее всего, произойдет до вызова main.Это будет выглядеть примерно так:

size_t load_parameter() {
    //do magic;
    return 42;
}

lru_cache<int, float> cacheMaker()
{
    static size_t STATES_NO_LRU = -1;
    if (STATES_NO_LRU == -1)
    {
        STATES_NO_LRU = load_parameter();
    }
    return lru_cache<int, float>(STATES_NO_LRU);

}
lru_cache<int, float> states_action0 = cacheMaker();

int main()
{
}
0 голосов
/ 11 октября 2018

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

class Singleton {

private: 
    // Let's prevent any other instances of this object 
    // by making the constructor private
    Singleton() 
      : states_action0(STATES_NO_LRU) // Here we initialize states_action0 to STATES_NO_LRU
    {
    } 

    // This member will be accessible everywhere and only has one instance
    cache::lru_cache<int, float> states_action0; 
    // You could also put states_action1 here too.
public: 

    static Singleton& GetInstance() {
        static Singleton theSingleton;
        return theSingleton;
    }

    // For read-only access make this const
    lru_cache& GetCache() { 
        return states_action0; 
    }
};

Тогда вы будете использовать его в любом месте приложения:

int main() {

    cache::lru_cache& states_action0 = Singleton::GetInstance().GetCache();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...