В рамках класса «сообщение» я пытаюсь передавать указатели разных типов, приводя их к указателям типа void* и сохраняя их в классе-оболочке («MsgData»), который запоминает исходный тип указателя.
Например, логический указатель:
bool* data = new bool;
event.wheel.y < 0 ? *data = false : *data = true;
send("all", this, MSG_MOUSE_SCROLL, MsgData(data));
Вызывается совместимый конструктор MsgData, и переменная сохраняется как член моего класса сообщений:
MsgData(): type_(NULLPTR), data_(nullptr) {} // Null
MsgData(const bool* data): type_(BOOL), data_((void*)data) {} // Bool
MsgData(const std::string* data): type_(STRING_STD), data_((void*)data) {} // std::string
// ... etc.
Я могу вернуть указатели обратно и использовать их без каких-либо ошибок, но когда я пытаюсь их удалить, программа вылетает:
~MsgData() {
switch (type_) {
case (BOOL):
if ((bool*)data_)
delete (bool*)data_;
break;
// ... etc.
}
}
Указатель bool — это просто пример, и то же самое происходит со всеми другими типами и классами. Программа вылетает только при попытке удалить указатель. Вернуть им исходный тип и использовать их не проблема.
Я исследовал проблему и нашел аналогичный вопрос, например этот в StackOverflow, но пока он Кажется, считается плохим стилем указывать указатель на void* и обратно. Я не могу найти причину сбоя программы.
static_cast
в коде C++, чтобы сделать ваши намерения более очевидными. - person Arnav Borborah   schedule 11.02.2018boost::variant
? - person Nawaz   schedule 11.02.2018std::any
, чтобы разрешить почти любые данные без необходимости делать эту перегрузку и вводить код списка. Вы получаете производительность, гибкость и типобезопасность. - person nwp   schedule 11.02.2018variant
делает программу проще, чем создание вашей собственной. Если вам не нужен Boost и у вас нет доступа к стандартной, есть ещеmpark::variant
, которая действует точно так же, как стандартная, но может использоваться без C++17 и является отдельной библиотекой. - person chris   schedule 11.02.2018new
иdelete
, а затем проверьте журнал, где они не совпадают. В качестве альтернативы, если вы используете Linux, пропустите-fsanitize=undefined,address
, чтобы этот тип ошибок был проанализирован во время выполнения. - person nwp   schedule 11.02.2018delete
, можно объяснить и другими причинами, например повреждением памяти. - person user4815162342   schedule 11.02.2018