我目前正在研究一些需要在运行时实例化半任意c ++类的代码。用户输入“ Class1”,将实例化Class1
的新实例。
所有这些都必须以void *形式存储,因为这些类不必共享任何基类(我也想支持基元,但我目前不支持)。
在使用时将void *强制转换为正确的类型,但是问题在于,我还允许它们用作指向基类的指针。
例如
void* p = new Derived();
((Base*)p)->someVirtualFunction();
我需要一种正确投射到基地的方法。显然,如果我拥有易于访问的类型,则可以:
void* p = (Base*)(new Derived());
((Base*)p)->someVirtualFunction();
不会有问题。
但是我没有那种容易使用的类型。
我确实有一个基础架构:
class Type {};
template<typename T>
class TypeImpl : public Type {};
在实际代码中,它们具有许多与手头问题无关的功能。
我可以访问指向Type*
的{{1}}和指向TypeImpl<Base>
的{1>}
我正在尝试找到一种使用这些方法正确投射指针的方法 例如
TypeImpl<Derived>
但没有虚函数模板,我找不到实现此目的的方法。
对于其他解决方案,我最接近的想法可能是某种在class Type {
void* cast(Type* type_of_p, void* p)=0;
template<typename C>
void* castTo(void* p)=0;
};
template<typename T>
class TypeImpl : public Type {
void* cast(Type* type_of_p, void* p){
return type_of_p->castTo<T>(p);
}
template<typename C>
void* castTo(void* p){
return ((C*) ((T*) p));
}
};
上进行索引的函数指针的散列表的散列表,但我也无法使其正常工作。
这有可能吗?如果可以的话,我该怎么做?
编辑以明确声明:
我有一个指向std::type_index
的{{1}},我需要将其强制转换为void* p
(例如Derived
)
Base*
或任何不使用运行时信息的类型转换都无效,因为该vtable未对齐。
我需要类似的东西:
void* p = new Derived();
(或等效的c ++强制类型转换),但我不知道它是哪个派生类。
我不确定我的措辞是否很差,还是我犯了一些错误,但这是核心问题。
答案 0 :(得分:1)
首先,我建议使用C ++强制转换,而不要使用普通的旧C强制转换,例如static_cast
,reinterpret_cast
,dynamic_cast
和const_cast
。它们比C型强制转换更安全,因为它们只做一件事。
由于您提到您有一个指向要尝试转换为基类/派生类的对象的指针,因此可以使用decltype
。
decltype
是C ++ 11说明符,它产生作为参数传递的变量的类型。
因此,您可以使用类似reinterpret_cast<decltype(base_pointer)>(value)
的东西。
有关更多信息,请查看以下资源:
https://en.cppreference.com/w/cpp/language/decltype
Cast a value using decltype, is it possible?
When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?
评论中的讨论指出,最初的问题要求运行时方法,而decltype
是编译时。尽管如此,以上内容可能是有意义的,因此我将对运行时方法添加一些想法。
C ++模板系统和类型推导机制在编译时运行。如果要在运行时处理动态类型系统(即由用户输入确定使用的类型),则必须使用工厂方法。
但是,也许有必要考虑是否有更好的方法。