A student
A student

Reputation: 180

C++ Inheritance Overriding Vector Member Variable

Say you had an class

class Foo
{
  // stuff
};

and you had a derived version of that class

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

and you had a class with a vector of pointers to Foos.

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

Could you derive FooManager into BarManager where BarManager has a vector of pointers to 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. 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.

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

Upvotes: 0

Views: 186

Answers (2)

Chris Dodd
Chris Dodd

Reputation: 126203

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:

class Baz : public Foo {  // whatever

You could convert a BarManagar * into a FooManager *

FooManager *ptr = &SomeBarManager;

and then stick a Baz into it's data

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.

Upvotes: 0

Werner Henze
Werner Henze

Reputation: 16726

No, that is not possible.

As one user pointed it it looks like a XY problem. You should better explain what you want to achieve.

Given only the few explanation...

One solution is to use std::vector<Foo*> objects; in FooManager and in BarManager to have functions that take objects and cast the pointers in objects to 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; or Manager<Bar> mgr;.

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

Upvotes: 1

Related Questions