Reputation: 180
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 Foo
s.
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
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
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