从基类函数派生的类容器

Posted

技术标签:

【中文标题】从基类函数派生的类容器【英文标题】:Derived class container from base class functions 【发布时间】:2015-11-15 12:08:25 【问题描述】:

我想根据派生类型更改位于基类中的容器中对象的类型。 (所以派生类认为它是一个指向类型“MyT : T”的指针容器,而基类认为它存储的是指向类型“T”的指针。)

目前我面临以下情况。我只是想知道是否有更好的解决方案。

考虑这个最小的例子

class Component

public:
    void Update();
;

class MyComponent: public Component

public:
    void Update() override ;
    void Draw();
;

class Foo

public:
    std::vector<Component*> _components; //this container needs to return different types depending on which class is accessing it, so Foo gets a "Componeent*", and MyFoo gets a "MyComponent*.
    void Update()
    
        for (int i = 0; i < _components.size(); i++)
        
            _components[i]->Update();
        
    
;

class MyFoo : public Foo //i guarantee that every pointer in the container in this derived class is of type "MyComponent" rather then "Component"

public:
    void Draw()
    
        for (int i = 0; i < _components.size(); i++)
        
            ((MyComponent*)_components[i])->Draw(); //how can i remove this cast? (every function in this class makes the same cast)
        
    
;

int _tmain(int argc, _TCHAR* argv[])

    MyFoo test;
    test.Update(); //should call the basic update
    test.Draw(); //should call the draw of the derived type

    //for clarification consider:
    //test._components <- should be container of type "MyComponent*"
    //((Foo)test)._components <- should be container of type "Component*"
    // note that both examples above are thesame objects, all of actual type "MyComponent" becouse test is of class "MyFoo"

在这个例子中,我希望 MyFoo 能够访问 Foo 中指定的容器。但是,在 MyFoo 类中,我保证容器中的所有条目都是 MyComponent 类型。因此,我制作的演员阵容将成功并发挥作用。

但是,为我调用的每个函数强制转换类型看起来很难看,而且很难维护,因为有许多函数需要这种特定类型。此外,每个单独的函数每次使用时都必须强制转换此条目。

我想知道是否有办法将位于 Foo 中的容器从“组件”类型更改为“MyFoo”类中的“MyComponent”类型,而不会破坏 Foo 提供的功能。

这样 MyFoo 中的每个函数都可以像访问 MyComponent* 一样访问它,但是从 Foo 继承的函数仍然像 Component* 一样工作(除了它调用被覆盖的函数而不是原始函数)。

我假设我缺少一些模式,或者我应该为此使用模板。 但我似乎无法弄清楚这一点。

[编辑] 我不是试图从指向“组件”的指针中调用“绘图”,我或多或少是在寻求一种方法来使位于“Foo”中的容器根据派生类更改其类型. (在这种情况下,“Foo”的容器在“Foo”的实例中具有类型“Component*”(如在其声明中一样)。但将类型“MyComponent*”存储在“MyFoo”的实例中(即使从“Foo”应该仍然有效(在这种情况下被覆盖)。

[Edit2] 可以通过创建派生类型的新容器来实现相同的目的。但是 id 必须将每个指针存储两次,我想知道这是否可以仅使用 1 个向量来实现。

【问题讨论】:

【参考方案1】:

好吧,要在指向基类实例的指针中使用派生类函数,基类中的函数应该是virtual。为此目的使用了virtual function table。此外,您的 Component 类必须声明 Draw 方法,如果函数在基类中定义没有意义,甚至可能是纯 virtual(即 virtual void Draw() = 0)。

【讨论】:

但是“组件”的每个派生类都需要是抽象的,或者具有绘图的实现。而“组件”本身不能是一个实例。我希望组件是一个可实例化的类,并且我只希望对给定类有意义的方法是可见的。因此,如果我创建 MyComponent2 : 具有 UpdateState 函数的组件,则 Draw 在此上不可见 虽然 MyComponent 'disables' Update 函数我不确定如果不使用元编程,这是否可能。 我无意“隐藏”更新功能。示例已更新。请注意,它旨在让“Foo”按预期使用正常多态性调用覆盖函数。

以上是关于从基类函数派生的类容器的主要内容,如果未能解决你的问题,请参考以下文章

从基类调用派生类函数

从基类调用派生类中的函数

如何从基类调用派生类函数?

C++派生类是不是可以从基类继承静态数据成员和静态成员函数?

如何通过派生类函数从基类更改向量

从基类到派生类的静态转换后找不到成员函数