Инициализировать статический массив класса шаблона с производным типом класса
У меня есть программа с основной функцией, которая просто печатает строку. Когда я запускаю эту программу, она вылетает без вывода в консоли. Я обнаружил, что проблема возникает, когда я вставляю элемент в карту 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
,