Monthly Archives: August 2011

C++: Mixing containers and inheritance

This is the sort of thing in C++ which catches me out as a recovering former Java programmer.

Amongst the very good advice I was given whilst learning C++ was:

  1. Use the STL containers
  2. Only use pointers when you really need to

The first point is sound advice, after all, why re-invent the wheel? There are plenty of useful containers like std::vector in the library.

The second point is about memory management. It’s much better to let scoping and destructors do the work for you, rather than keeping track of pointers and calling delete().

With this in mind, here’s a sample program:

#include <iostream>
#include <vector>

class Animal
{
public:
    virtual void hello();
};

class Dog : public Animal
{
public:
    virtual void hello();
};

void Animal::hello()
{
    std::cout << "<Generic Animal Noise>" << std::endl;
}

void Dog::hello()
{
    std::cout << "Woof" << std::endl;
}

int main()
{
    // store the object directly
    std::vector<Animal> animals;
    animals.push_back(Dog());
    animals[0].hello();

    // store the pointer
    std::vector<Animal*> animalPtrs;
    animalPtrs.push_back(new Dog);
    animalPtrs[0]->hello();
}

What’s it supposed to print? Well I thought it should print

Woof
Woof

but instead it prints

<Generic Animal Noise>
Woof

I was genuinely surprised by the result – the lesson here is to use pointers if you don’t want your class to lose its identity.

This was also discussed in this forum post and (in great detail) in “STL and OO Don’t Easily Mix”.

Update: Apparently this behaviour is called slicing. Well I really have learnt something today.

Posted in Uncategorized | Leave a comment