这可能已经有了答案,但我无法找到我尝试过的确切案例。
假设您有类似通用变体的类(省略了相关的详细信息):
/* in hpp file */
struct Base {
void * data;
Base();
virtual ~Base();
// ...
virtual bool Read(...);
}
template <Some_Enum_Class T>
struct Derived : Base {
// T-specific interface to deal with Base::data
bool Read(...); /* implementation in separate cpp file */
}
出于特定于项目的原因,这种变体类型可以引用表示该相同变体类型的集合的容器。也就是说,某些Derived中的void *数据将存储明确定义的类型,并且这些类型最终可能会导致Derived的另一个变体,并且不知道哪个提前(在编译期间它不可能)数据必须无效*。
Base可以在必要时跟踪T,并且可以在Derived构造函数中将其设置为实例常量。
我不确定在创建Derived实例后会发生什么,并将其(作为Base *)存储在void *中。
如果我取出void *并将其转换为Base *(因为我不能在运行时获取类型信息,也不想超出此处已发生的事情),将调用尽管编译器无法确定T是什么,但像Read这样的函数正确使用Derived版本?
在代码中:
Derived <1> * D = new Derived <1>;
Base * B = (Base*) D; // c-cast for brevity unless this is part of the answer
SendAsVoidPtr( (void*) B ); // at this point the type information is lost
然后再
void * arg = ReceiveVoidPtr();
Base * B = (Base*) arg;
Base->Read(...); // which version does this call and why?
我猜测(希望)vtable只依赖于地址(作为void *或Base *),所以这应该工作afidek并调用Derived&lt; 1&gt; :: Read()函数,尽管编译器(可能)无法提前确定类型,但我希望在构建此结构之前确定...
答案 0 :(得分:1)
指向vtable
的指针实际上是Base
中的隐藏实例成员(在大多数实现中),所以是的,您可以调用Read
和其他虚拟的正确覆盖功能