Question

I want to create a collection in C++ of type Parent, where I add different subclasses like Child and Child2, and then get all the elements of X subclass. I tried with a vector, but it happens to destroy polymorphism according to this answer. If I use a collection of pointers, I would have to iterate over it sequentially checking the class of every element, is there a better / more efficient solution?

Here's an example code:

class Parent
{
   public:
     int id;
     Parent(){ id = 8; }
};

class Child: public Parent
{
     int foo;
   public:
     Child(int n){ foo= n; }
};

class Child2: public Parent
{
     int bar;
   public:
     Child2(int n){ bar= n; }
};

Pseudocode:

GenericCollection<Parent> collection; //Full of elements Child and Child2.

This is the method I want to implement:

collection.getElements<Child2>();

Thanks for everything.

Was it helpful?

Solution

You cannot do this with objects because of the object slicing problem. You need to use pointers instead - preferably, smart pointers, such as unique_ptr<Parent>:

GenericCollection<unique_ptr<Parent>> collection;    

Now you can implement your getElements method that uses Run-Time Type Information (RTTI) to detect the type of the object pointed to by the smart pointer, and keep only the ones pointing to Child2.

Note that in order to use RTTI your base class Parent needs to have at least one virtual member function. This shouldn't be an issue in your case, because you expect polymorphic behavior.

OTHER TIPS

In C++ you can't directly do what you're asking, because items are stored "by value" in the vector, so you'll only end up with the parent portion of each object while the child-specific parts will be sliced away.

However we may be able to solve your real problem.

If you really need to be able to generate separate lists of child1 and child2 objects, the C++ idiom would be separate vectors to contain each different type.

If however all you need is polymorphism, then you could have a vector of (smart) pointers to the base class, and operate on those polymorphically. If you take this approach don't try to get a list of a specific child's objects but instead utilize an appropriate abstract interface to perform your logic.

In this case you can't. Read about object slicing for more information.

It will only work if you have a collection of pointers. For this I recommend you read about std::unique_ptr.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top