1

I saw that many people use new to create instances of the derived classes and then they keep a pointer to base in some container. Does that have any advantage with respect to using a container for each derived class? With this I meant something like the following

class A
  {
 public:
  vector<Base*> bases;
  set<Derived1> der1;
  set<Derived2> der2;
  //other stuff
  };

Edit: removed the second part of the question and added as a comment.

German Capuano
  • 5,183
  • 6
  • 23
  • 35
  • What are you going to do when someone adds a new derived type? – PlasmaHH Jun 26 '13 at 20:19
  • adding a new set to the class A? anyway, all the functionality should come from the base, so there shouldn't be any problem. Or you meant to the hetcontainer? – German Capuano Jun 26 '13 at 20:28
  • Make sure you understand the difference between compile time and run time. – Kerrek SB Jun 26 '13 at 20:45
  • Additionally, since c++11 allows for template classes with variable number of arguments, wouldn't it be possible to define something that behaves as an heterogeneous container? I imagine something like calling `hetcontainer mycontainer;`. Then `hetcontainer` could be similar to the `class A` with an `emplace()` overloaded for each derived class. – German Capuano Jun 26 '13 at 21:43

1 Answers1

0

If you do the following

vector<base*> bases;

You can then use polymorphism on your objects. Imagine that you have a base class named Vehicule. It has a move() method to go from point A to point B.

class Vehicule
{
  public:
    virtual void move(){}
}

Then you have two derived classes : Car and Submarine

class Car : public Vehicule
{
  public:
    void move()
    {
       checktires(); 
       drive();
    }
}

And your Sub class

class Submarine : public Vehicule
{
  public:
    void move()
    {
       submersion(); 
       propulsion();
    }
}

Because the move method is a virtual one, you'll be performing polymorphism. Which is a mechanism that allows you to call the same function but have different behaviours based on the dynamic type of your objects.

I'll try to explain that sentence the best I can. Now that you have the Vehicule, Car and Submarine classes, you will create an array (or a stl containers like a vector) of Vehicule pointers.

std::vector<Vehicule*> objects; 
objects.push_back(new Car());
objects.push_back(new Submarine());
objects[0]->move();
objects[1]->move();

The first call to move will call the move method defined in the Car method. And the second one will call the move defined in Submarine. Because you may have a vector of Vehicule* but when you call the function and because it is virtual, you are calling the appropriate version of it. And by calling only one function you have different behaviours. You may add as many derived class of Vehicule, you just have to adapt the move method.

You should search stackoverflow for polymorphism, there are far more detailed and accurate answers that the one I just wrote.

Sorry for the mistakes, I'm not a native-english speaker.

Silouane Gerin
  • 1,201
  • 10
  • 13
  • what I meant with the question is more about why to use `new Car` and `new Submarine` for each one of them, instead of keeping all the cars and submarines in some containers. I'm going to create millions of instances of the derived classes, so I feel uncomfortable about calling so many times `new` instead of creating just one set. – German Capuano Jun 26 '13 at 20:45
  • That way you work on pointers. You can have a `std::vector objects;` if you feel more comfortable with it. Polymorphism works for both pointers and references. And instead of having multiple containers with different derived classes (what if you have 300 derived classes ?) and iterating on them, you can have a unique container. – Silouane Gerin Jun 26 '13 at 20:52
  • 1
    Are you worried about memory fragmentation? You want somehow to allocate many "Cars" in a single memory chunk? Don't. Trust your C++ library's memory allocator. If this proves to be a performance bottleneck in your code, you can always supply some sort of fancy custom allocator. But really, it won't be. Write your code in the cleanest way possible. – Peter Jun 26 '13 at 20:54
  • and what about calling millions of times to `new`? isn't it slow? – German Capuano Jun 26 '13 at 21:49