gpt4 book ai didi

c++ - 如何在运行时正确地将指向派生类的 void* 转换为指向基类的 void*

转载 作者:行者123 更新时间:2023-11-28 04:34:58 26 4
gpt4 key购买 nike

我目前正在编写一些需要允许在运行时实例化半任意 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 上的函数指针 HashMap 的某种 HashMap 。但我也无法让它发挥作用。

这可能吗?如果可能,我该怎么做?

编辑希望澄清:

我有一个 void* p指向 Derived我需要将其转换为 Base*(例如 void* p = new Derived();)

(Base*)p或任何不使用运行时信息的类型转换都是无效的,因为 vtable 未对齐。

我需要这样的东西: (Base*)(Derived*)p (或等效的 C++ 转换)但我不知道它是哪个派生类。

我不确定是我的措辞很糟糕还是我犯了一些错误,但这是核心问题。

最佳答案

首先,我建议使用 C++ 转换,而不是普通的旧 C 转换,例如 static_cast , reinterpret_cast , dynamic_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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com