Objects of different classes in one vector?

In my code, I have a set of objects:

class Sphere { ... class Plane { ... ... 

And I need to use their set (they will all have different types) in vector . How to add objects of different classes in vector ?

+4
source share
6 answers

A sphere and plane will require a common base type, or your vector should consist of void* .

Common base type (better):

 class Shape { ... }; class Sphere : public Shape { ... }; class Plane : public Shape { ... }; std::vector<Shape*> shapes; 

or void* (not big):

 std::vector<void*> shapes; 
+7
source

Classes must have a common base class, for example:

 class MyBase { }; class Sphere : public MyBase { }; class Plane : public MyBase { }; 

Then, to store polymorphic objects in a vector, you must keep a pointer to them (because they can be of different sizes from the base class). I recommend using std::shared_ptr<MyBase> or std::unique_ptr<MyBase> (or use Boost if C ++ 0x is not available).

 std::vector<std::shared_ptr<MyBase> > v; v.push_back<std::shared_ptr<MyBase>(new Sphere()); v.push_back<std::shared_ptr<MyBase>(new Plane()); 

If there is no common base, you will need to use void* or find another way to do this.

+7
source

Creating containers of polymorphic types are classic solutions that have their own problems. One of which types must be polymorphic just to add them to the container is not a good reason. Another problem is the early and tight connection, which leads to more complicated maintenance and lack of flexibility, just to add them to the container is not a good reason. Fortunately, there are better alternatives in C ++.

The best solution would be to store functions, not the objects themselves in containers. A common reason why you want to put different types in the same container is to perform the same actions for all of them, for example, Sphere::Draw() or Plane::Draw() . What you can do is create a container for drawing and wash. For instance.

 vector<function<void()>> drawings; Sphere s; Plane p; drawings.push_back(bind(s, &Sphere::Draw)); drawings.push_back(bind(p, &Plane::Draw)); for(auto I = drawings.begin(); I != drawings.end(); ++i) (*i)(); 

Thus, you avoided strong communication and other inheritance problems and got a more flexible, more general solution.

The above solution only works with C ++ 11 , since it requires std :: function ()

+3
source
 Class Shape{...code...} Class Sphere : public Shape{...code...} Class Plane : public Shape{...code...} std::vector<Shape*> List; List.push_back(new Sphere); List.push_back(new Plane); 

or

 //Base class to derived class Shape* Shape_Sphere = new Sphere(); Shape* Shape_Plane = new Plane(); std::vector<Shape*> List; List.push_back(Shape_Sphere); List.push_back(Shape_Plane); 

and if you want to remove pointers

 std::vector<Shape*>::iterator it; for(it = List.begin(); it != List.end(); ++it) { delete *it; } 

Since the vector stores instances of Shape and Sphere / Plane from the Shape base class, C ++ will allow this to work.

+1
source

Are objects interconnected? If this is not the case, then you probably should not do this.

If so, you'll want to do some readings on inheritance .

0
source

Other posts have told you the most about what you need to know. I would like to add that boost has pointer containers, which can be convenient as they clear the contents where they are destroyed. Boost manual

0
source