基类函数

时间:2015-11-15 12:08:25

标签: c++ inheritance polymorphism containers

我想根据派生类型更改位于基类中的容器中的对象类型。 (因此派生类认为它是指向“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类中,我保证容器中的所有entrins都是MyComponent类型。因此,演员阵容将成功并发挥作用。

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

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

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

我假设我错过了一些模式,或者我应该使用模板。 但我似乎无法想出这个。

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

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

1 个答案:

答案 0 :(得分:0)

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