Objects of different classes in a single vector?

2019-01-24 18:04发布

In my code, I have a set of objects:

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

And I need to use a collection of them (they will all have different types) in a vector. How would I add objects of different classes to a vector?

标签: c++ class vector
6条回答
趁早两清
2楼-- · 2019-01-24 18:38
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 delete the 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 are derived of the base class Shape, C++ will allow this to work

查看更多
时光不老,我们不散
3楼-- · 2019-01-24 18:40

The other posts have told you most of what you need to know. I would like to add that boost has pointer containers that might be handy as they cleanup there contents when they are destroyed. Boost manual

查看更多
何必那么认真
4楼-- · 2019-01-24 18:46

The classes would need to have a common base class, e.g.:

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

Then in order to store polymorphic objects in a vector, you must store a pointer to them (because they can be different sizes from the base class). I recommend using a std::shared_ptr<MyBase> or std::unique_ptr<MyBase> (or use Boost if C++0x isn't 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'd have to use void*, or find a different way to do this.

查看更多
啃猪蹄的小仙女
5楼-- · 2019-01-24 18:47

Creating containers of polymorphic types is a classical solutions, which comes with its own problems. One of which the types have to become polymorphic just in order to add them to a container -- not a good reason. Another problem is early and tight coupling resulting in more difficult maintenance and lack of flexibility, just in order to add them to a container -- not a good reason. Fortunately, in C++ there are better alternatives.

A better solution would be storing functions and not objects themselves in containers. The common reason why you want to put different types in the same container is to perform the same actions on all of them, for example, Sphere::Draw() or Plane::Draw(). What you can do is create a container of draw functions instead and erase type. E.g.

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)();

By doing that you avoided strong coupling and other problems of inheritance, and got a more flexible, more general solution.

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

查看更多
劫难
6楼-- · 2019-01-24 18:47

Are the objects related in a meanginful way? If they're not, then you probably shouldn't.

If they are, you'll want to do some reading on inheritance.

查看更多
狗以群分
7楼-- · 2019-01-24 18:51

Sphere and Plane would need a common base type, or your vector would need to be composed of void*'s.

Common base type (better):

class Shape { ... };
class Sphere : public Shape { ... };
class Plane : public Shape { ... };

std::vector<Shape*> shapes;

or void*'s (not great):

std::vector<void*> shapes;
查看更多
登录 后发表回答