我想根据派生类型更改位于基类中的容器中的对象类型。 (因此派生类认为它是指向“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个向量来实现。
答案 0 :(得分:0)
好吧,要在指向基类实例的指针中使用派生类函数,基类中的函数应该是virtual
。有virtual function table用于此目的。此外,如果函数无法定义,Component
类必须声明Draw
方法,甚至可能是纯virtual
(即virtual void Draw() = 0
)基类有。