Question

The following code, prints out

Derived
Base
Base

But I need every Derived object put into User::items, call its own print function, but not the base class one. Can I achieve that without using pointers? If it is not possible, how should I write the function that deletes User::items one by one and frees memory, so that there should not be any memory leaks?

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

class Base{
public:
  virtual void print(){ cout << "Base" << endl;}
};

class Derived: public Base{
public:
  void print(){ cout << "Derived" << endl;}
};

class User{
public:
  vector<Base> items;
  void add_item( Base& item ){
    item.print();
    items.push_back( item );
    items.back().print();
  }
};

void fill_items( User& u ){
  Derived d;
  u.add_item( d );
}

int main(){
  User u;
  fill_items( u );
  u.items[0].print();
}
Was it helpful?

Solution

You need to use pointers, and you need to give your base class a virtual destructor. The destructor does not have to do anything, but it must exist. Your add function then looks like:

void add_item( Base * item ){
    item->print();
    items.push_back( item );
}

where items is a vector<Base *>. To destroy the items (assuming a virtual destructor):

for( int i = 0; i < items.size(); i++ ) {
    delete items[i];
}
items.clear();

OTHER TIPS

You need a virtual destructor for base to make sure objects of type Derived get destroyed properly when calling delete on a pointer of type Base.

class Base{
public:
  virtual void print(){ cout << "Base" << endl;}

  virtual ~Base( ) { }  // virtual destructor
};

Then you can use Boosts ptr_vector to store pointers to your objects that get deleted when the container gets destroyed.

just explaining:

In order to understand what is going on, you may try to define class Base abstract (e.g. defining any method pure virtual). In this case I expect you'll see compiler errors. This way you'll recognize what vector actually does: it creates new instances of class Base by means of copy construction when you push_back( derived ). This is why you want to use pointers instead. Then vector works with your originally created objects of type Derived instead of own copies of type Base.

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