Моя статическая карта всегда пуста - PullRequest
2 голосов
/ 26 марта 2011

Я объявил статическую неупорядоченную карту в файле заголовка следующим образом:

static boost::unordered_map<KeyAction, sf::Key::Code> WindowKeyMap;

в том же файле заголовка, у меня есть функция, которая заполняет карту некоторыми значениями:

static void Initialize(std::string &file)
{
    WindowKeyMap[MoveLeft] = sf::Key::Code::Left;
    WindowKeyMap[MoveRight] = sf::Key::Code::Right;
    WindowKeyMap[MoveUp] = sf::Key::Code::Up;
    WindowKeyMap[MoveDown] = sf::Key::Code::Down;
    std::cout << std::endl << WindowKeyMap.size() << std::endl;
}

Позже в моей программе внутри отдельного класса / функции я пытаюсь прочитать одно из значений:

std::cout << std::endl << WindowKeyMap.size() << std::endl;
auto test2 = WindowKeyMap[MoveRight];

, но карта всегда пуста.Выход на консоль всегда равен 4 из процедуры инициализации, а затем 0 из второй команды.Я думал, что статические карты были постоянными во всей программе, поэтому я немного озадачен тем, как моя статическая карта становится пустой.Кто-нибудь может пролить свет?

Спасибо

Ответы [ 2 ]

9 голосов
/ 26 марта 2011

Когда вы объявляете свою переменную в заголовке таким образом, каждый модуль компиляции (* .cpp) получает свою собственную локальную статическую копию.Вы должны заявить об этом extern

extern boost::unordered_map<KeyAction, sf::Key::Code> WindowKeyMap;

и в один cpp положить

boost::unordered_map<KeyAction, sf::Key::Code> WindowKeyMap;
1 голос
/ 26 марта 2011

Просто: просто не делай этого. Хотя вы можете избавиться от инициализации и области видимости, предложенных @Eelke, в долгосрочной перспективе вы будете стрелять себе в ногу ... Вы действительно хотите, чтобы хеш-таблица была доступна всем и везде? Вы действительно принимаете на себя риск неконтролируемого доступа к (очевидно важным) данным? Вы действительно хотите иметь непроверяемое глобальное состояние во всем приложении? Вы действительно хотите, чтобы все зависимости, введенные <unordered_map>, были включены во многие блоки перевода вашей программы? Я мог бы продолжать так некоторое время, но суть в том, чтобы обернуть логику и данные в класс и предоставить сервис через интерфейс. Создайте экземпляр интерфейса через фабрику или контейнер зависимостей и явно управляйте временем жизни этого объекта.

С уважением,

Пол

...