我目前正在研究一些需要允许在运行时实例化半任意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_castreinterpret_castdynamic_castconst_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/

10-12 12:43
查看更多