polymorphism:使用基指针的模板化派生类的非模板化基础

时间:2015-07-20 07:32:29

标签: c++ templates inheritance casting

这可能已经有了答案,但我无法找到我尝试过的确切案例。

假设您有类似通用变体的类(省略了相关的详细信息):

/* 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()函数,尽管编译器(可能)无法提前确定类型,但我希望在构建此结构之前确定...

1 个答案:

答案 0 :(得分:1)

指向vtable的指针实际上是Base中的隐藏实例成员(在大多数实现中),所以是的,您可以调用Read和其他虚拟的正确覆盖功能