多态性:非模板化基础与模板派生类,使用基指针 [英] polymorphism: non-templated base with templated derived class, using base pointer

查看:139
本文介绍了多态性:非模板化基础与模板派生类,使用基指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这可能已经有答案了,但是我找不到我想要的确切情况。

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

这样的变体类型将有可能指代表示该相同变体类型的集合的容器。也就是说,一些Derived中的void *数据将存储良好定义的类型,并且这些类型可能最终导致Derived的另一个变体,并且不知道提前的时间(在编译期间不可能)数据必须是void *。

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*.

Base可以根据需要跟踪T,它可以在Derived构造函数中设置为实例常量。

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

我不知道是什么发生后,我创建一个Derived的实例,并将其(作为Base *)存储在一个void *。

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*.

如果我把void *转换为Base *(因为我不能从运行时获取类型信息,也不想超出这里已经发生的事情),将调用函数,如Read正确使用Derived版本,尽管编译器无法确定T是什么?

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?

在代码中:

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只取决于地址*),所以这应该工作afaik和调用Derived< 1> :: Read()函数,尽管编译器(可能)无法确定提前的类型,但我想确保之前建立的顶部这个结构...

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...

推荐答案

指向 vtable 的指针本质上是一个隐藏实例成员 Base (在大多数实现中)所以是的,你可以调用读取的正确覆盖其他虚拟功能。

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.

这篇关于多态性:非模板化基础与模板派生类,使用基指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆