polymorphism: non-templated base with templated derived class, using base pointer

空扰寡人 提交于 2019-12-25 03:07:45

问题


This may already have an answer but I've not been able to find an exact case of what I'm attempting.

Suppose you have some generic variant-like class like so (irrelevant details omitted):

/* 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 */
}

For reasons specific to the project, it will be possible for such a variant type to refer to containers representing collections of this same variant type. That is, void* data within some Derived will store well-defined types, and those types may eventually lead back to another variation of Derived, and not knowing which ahead of time (it won't be possible during compilation) data must be void*.

It is acceptable for Base to keep track of T if necessary, and it can be set as an instance constant within Derived constructors.

What I'm not sure of is what happens after I create an instance of Derived, and store it (as a Base*) in a void*.

If I take the void* and cast it to Base* (as I won't be able to obtain type information out of runtime nor do I want to beyond what's happening here already), will calling functions like Read correctly use the Derived version despite the fact that the compiler is unable to determine what T is?

In code:

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

then later

void * arg = ReceiveVoidPtr();
Base * B = (Base*) arg;
Base->Read(...); // which version does this call and why?

I'm guessing (hoping) that the vtable depends only on the address (as void* or Base*), so this should work afaik and call the Derived<1>::Read() function despite the compiler being (probably) unable to determine the type ahead of time, but I'd like to be sure before building on top of this structure...


回答1:


The pointer to vtable is essentially a hidden instance member in Base (in most implementations) so yes you'll be able to call correct overrides of Read and other virtual functions.



来源:https://stackoverflow.com/questions/31510970/polymorphism-non-templated-base-with-templated-derived-class-using-base-pointe

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!