Отобразить пустоту * обратно в исходный тип

0

Я создаю Lua api для своей программы. Я хочу иметь возможность сделать следующее:

void* CreateA()
{
     A* a = new A();
     PointerTypes[a] = A;
     return reinterpret_cast<void*>(a);
}

void* CreateB()
{
     B* b = new B();
     PointerTypes[b] = B;
     return reinterpret_cast<void*(b);
}

void DeleteThing( void* p )
{
     typename type = PointerTypes[p];
     type* t = reinterpret_cast< type >( p );
     delete t;
}

Есть ли простой способ сделать это? PS: Мое приложение уже использует RTTI, поэтому его можно использовать и здесь.

  • 0
    Вкратце нет. После того, как вы выбросили информацию о типе, вы не сможете получить ее обратно. Таким образом, любое решение будет включать хранение информации о типе где-либо.
  • 1
    Есть ли причина, по которой вы не используете общий базовый класс? (Это тот случай, если вы хотите использовать существующие типы, которые вы не можете изменить ...)
Показать ещё 3 комментария
Теги:
casting
rtti

1 ответ

2
Лучший ответ

Вместо сохранения типа на карте (что невозможно, потому что типы не являются объектами первого класса в C++), вы можете сохранить функцию делетера на карте. Затем ваша фабричная функция становится:

void* CreateA()
{
    A *a = new A();
    PointerDeleters[a] = [](void *obj) { delete static_cast<A*>(obj); };
    return a;
}

или с шаблоном функции:

template<typename T>
void* Create() // maybe you want to forward c'tor args using variadic template
{
    T *a = new T();
    PointerDeleters[t] = [](void *obj) { delete static_cast<T*>(obj); };
    return t;
}

А затем вызовите его, чтобы вызвать удаление объекта p с неизвестным типом:

void DeleteThing(void* p)
{
    PointerDeleters[p]();
}

Карта PointerDeleters должна иметь тип значения std::function<void(void*)>.

Лучшим решением будет (если ваш проект позволяет) использовать базовый класс с виртуальным деструктором; то вы можете просто удалить указатель на этот класс без сохранения дополнительной информации:

template<typename T>
BaseClass* Create()
{
    return new T();
}

void DeleteThing(BaseClass* p)
{
    delete p;
}
  • 0
    Именно то, что я искал! Один жесткий вопрос: зачем использовать static_cast а не reinterpret_cast ?
  • 0
    Смотрите здесь: stackoverflow.com/questions/310451/… Они разрешили использовать его в C ++ 11, но это все еще считается более опасным, потому что вы можете случайно сделать больше вредных вещей. Я предпочитаю static_cast если мне не нужно использовать reinterpret_cast .
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню