Skip to content
Tobias Widlund edited this page Jan 20, 2016 · 1 revision

PolymorphicWrapper

View the code in the repository

Purpose

With polymorphic types you often want to store them as the base class, to for example, fit them all in the same container. This lets you call virtual methods which works fine. However, deep-copying these objects when represented as the base class is a problem. One solution is to create a member function for cloning the instance which is virtual, but this is horrible to maintain and clumsy to use. This class template aims to solve this exact problem by acting as a wrapper around a polymorphic object to allow the use of the native copy constructing/assignment abilities of the object

Usage

Since this deals with polymorphism, let us first define some polymorphic types.

class Animal
{
    public: 
        virtual void makeNoise() const
        {   
            std::cout << "...\n";
        }   
};

class Monkey : public Animal
{
    public: 
        virtual void makeNoise() const override
        {   
            std::cout << "oh oh AH!\n";
        }   
};

class Giraffe : public Animal
{
    public: 
        virtual void makeNoise() const override
        {   
            std::cout << "moooo\n";
        }   
};

Let's make a useful alias to make the PolymorphicWrapper neater to work with. The template type passed is the base class of the polymorphic types you want to work with.

using PolymorphicAnimal = th::PolymorphicWrapper<Animal>;

Polymorphic animals can now be created, and copied. The wrapper ensures that the object is completely owned by the wrapper itself, and copying it will trigger the copy mechanics of the derived type being stored.

    PolymorphicAnimal animal1 = Monkey();
    PolymorphicAnimal animal2 = Giraffe();
    PolymorphicAnimal animal3 = animal1;

    std::vector<PolymorphicAnimal> animals{animal1, animal2, animal3};
    std::vector<PolymorphicAnimal> copyOfAnimals = animals;

To access the stored object of the wrapper, use the * or -> operators just like a pointer.

    for(auto& animal : copyOfAnimals)
        animal->makeNoise();

Output:

oh oh AH!
moooo
oh oh AH!
Clone this wiki locally