Я создаю 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, поэтому его можно использовать и здесь.
Вместо сохранения типа на карте (что невозможно, потому что типы не являются объектами первого класса в 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;
}
static_cast
а не reinterpret_cast
?
static_cast
если мне не нужно использовать reinterpret_cast
.