Инициализировать статический массив класса шаблона с производным типом класса

У меня есть программа с основной функцией, которая просто печатает строку. Когда я запускаю эту программу, она вылетает без вывода в консоли. Я обнаружил, что проблема возникает, когда я вставляю элемент в карту OperatorCore (symbolMap).

Это минимальный код:

//Binary.hpp
class Binary final : public OperatorCore, public StaticPool<Binary> {
public:
    Binary(int ID, std::string name)
        : OperatorCore(name), StaticPool<Binary>(ID) {
    }
    ~Binary() {}
};
//Binary.cpp
template<>
const Binary StaticPool<Binary>::pool[] = {
    Binary(0, "a string value")//without this line of code, it prints works
};

//OperatorCore.hpp
class OperatorCore {
public:
    static std::map<std::string, OperatorCore*> symbolMap;
    const std::string name;
    OperatorCore (std::string name);
    virtual ~OperatorCore () {}
};
//OperatorCore.cpp
std::map<std::string, OperatorCore*> OperatorCore::symbolMap{};
OperatorCore::OperatorCore(std::string name) : name(name) {
    symbolMap.insert({name, this});
}


//StaticPool
template<typename T, typename TKey = int>
class StaticPool {
public:
    const TKey ID;
    static const T pool[];
    StaticPool(TKey ID) : ID(ID) {}
    virtual ~StaticPool() {}
};

Проблема не возникает, если я удаляю одну из выделенных строк. Вызывает ли этот дизайн повреждение памяти?

РЕДАКТИРОВАТЬ: инициализация OperatorCore::symbolMap находится в том же файле, где также реализация конструктора OperatorCore.

2 ответа

Решение

Я подозреваю, что у вас есть проблема порядка инициализации. Другими словами, ваша программа пытается инициализировать pool до symbolMapи конструктор Binary объект вызывает базовый конструктор, который пытается использовать symbolMap, который еще не был построен.

Есть несколько решений для этого. Ваша лучшая ставка, вероятно, повернуть symbolMap статический член в статическую переменную внутри специальной функции получения:

class OperatorCore {
public:
    static std::map<std::string, OperatorCore*>& symbolMap() {
        static std::map<std::string, OperatorCore*> instance;
        return instance;
    }
};

У вас есть случай static initialization order fiasco, Это означает, что ваша статика может быть построена в неправильном порядке. Я не знаю, работает ли инициализация статических объектов в том же файле в правильном порядке. Но в противном случае вам следует отложить инициализацию пула, которая зависит от карты. Может быть, написать функцию для инициализации пула и вызвать его в начале вашего main,

Другие вопросы по тегам