我目前正在研究一些需要允许在运行时实例化半任意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*
的TypeImpl<Base>
和指向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
上进行索引的函数指针的哈希图的哈希图,但我也无法使其正常工作。这可能吗?如果可以,我该怎么做?
编辑以明确说明:
我有一个
void* p
指向Derived
,我需要将其强制转换为Base*
(例如
void* p = new Derived();
)(Base*)p
或任何不使用运行时信息的强制类型转换均无效,因为vtable未对齐。我需要类似的东西:
(Base*)(Derived*)p
(或等效的c ++强制转换),但我不知道它是哪个派生类。我不确定我的措辞是否很差,还是我犯了一些错误,但这是核心问题。
最佳答案
首先,我建议使用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 ++模板系统和类型推导机制在编译时运行。如果要在运行时处理动态类型系统(即,由用户输入确定使用的类型),则必须使用工厂方法。
但是,是否有更好的方法可能值得考虑。
关于c++ - 如何在运行时正确地将指向派生类的void *强制转换为指向基类的void *,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51746091/