简体   繁体   English

C++ Inheritance 覆盖向量成员变量

[英]C++ Inheritance Overriding Vector Member Variable

Say you had an class假设你有一个 class

class Foo
{
  // stuff
};

and you had a derived version of that class你有那个 class 的派生版本

class Bar : public Foo
{
  // extra stuff
};

and you had a class with a vector of pointers to Foo s.并且您有一个 class 带有指向Foo的指针向量。

class FooManager
{
public:
  std::vector<Foo*> objects;
}

Could you derive FooManager into BarManager where BarManager has a vector of pointers to Bar ?您能否将FooManager派生到BarManager中,其中BarManager有一个指向Bar的指针向量?

If you did something like如果你做了类似的事情

class BarManager : public FooManager
{
  std::vector<Bar*> objects;
}

Then BarManager would just be hiding FooManager 's objects and I wouldn't want that extra member.然后BarManager将只是隐藏FooManager的对象,我不想要那个额外的成员。 I could just push Bar pointers into the FooManager 's objects and that would work, but then if I wanted to use the extra stuff the Bar object has, I would need to cast all the Foo* s into Bar* s and then there would be problems if I accidentally pushed a Foo pointer into objects.我可以将Bar指针推入FooManager的对象中,这样就可以了,但是如果我想使用Bar object 拥有的extra stuff ,我需要将所有Foo* s 转换为Bar* s,然后会有如果我不小心将Foo指针推入对象中,则会出现问题。

Is there a better solution?有更好的解决方案吗?

EDIT: I am trying out different methods to organize a game's classes.编辑:我正在尝试不同的方法来组织游戏的课程。 All the objects are derived from a GameObject with pure virtual Update() and Draw() methods.所有对象都从具有纯虚拟 Update() 和 Draw() 方法的 GameObject 派生。 All objects belong to a manager of that object type, and then all those managers belong to one “Manager Manager” who will call the Update() and Draw() methods for the managers which in turn call the Update() and Draw() methods for the objects.所有对象都属于该 object 类型的管理器,然后所有这些管理器都属于一个“管理器管理器”,该管理器将为管理器调用 Update() 和 Draw() 方法,然后再调用 Update() 和 Draw()对象的方法。

No, that is not possible.不,那是不可能的。

As one user pointed it it looks like a XY problem.正如一位用户指出的那样,它看起来像是一个 XY 问题。 You should better explain what you want to achieve.你应该更好地解释你想要达到的目标。

Given only the few explanation...只给出了几个解释......

One solution is to use std::vector<Foo*> objects;一种解决方案是使用std::vector<Foo*> objects; in FooManager and in BarManager to have functions that take objects and cast the pointers in objects to Bar* .FooManagerBarManager中具有获取objects并将objects中的指针转换为Bar*的函数。

class BarManager : public FooManager {
    Bar* get_at_index(std::size_t i) const { return static_cast<Bar*>(objects[i]); }
}

Another approach is to use a templated class and then use either Manager<Foo> mgr;另一种方法是使用模板 class 然后使用Manager<Foo> mgr; or Manager<Bar> mgr;Manager<Bar> mgr; . .

template <class T>
class Manager
{
public:
  std::vector<T*> objects;
}

Not only is it not possible, it makes no sense to do so.不仅不可能,而且这样做毫无意义。 Imagaine what could happen if you could do this.想象一下如果你能做到这一点会发生什么。 If something like this was allowed:如果允许这样的事情:

class BarManager : public FooManager
{
  override std::vector<Bar*> objects;  // replace the base class member with this
}

Then if you defined another subclass of Foo:然后,如果您定义了 Foo 的另一个子类:

class Baz : public Foo {  // whatever

You could convert a BarManagar * into a FooManager *您可以将BarManagar *转换为FooManager *

FooManager *ptr = &SomeBarManager;

and then stick a Baz into it's data然后将 Baz 插入它的数据

ptr->objects->push_back(new Baz());

leading to predictable chaos when someone tried to later access it as if it was a Bar.当有人试图稍后访问它时,就好像它是一个酒吧一样,这会导致可预见的混乱。

So the real question is WHY are you thinking of trying to do something like this?所以真正的问题是你为什么想尝试做这样的事情? Because it really doesn't make any sense, and if you think it does, there is probably something fundamentally inconsistent in your design.因为它确实没有任何意义,而且如果你认为它有,那么你的设计中可能存在根本不一致的地方。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM