将void *映射回原始类型

时间:2013-12-21 15:37:49

标签: c++ casting rtti

我正在为我的程序创建一个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,因此也可以在这里使用。

1 个答案:

答案 0 :(得分: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;
}