#include <iostream>
#include <vector>

class Base
{
public:
    virtual ~Base() { }

    virtual void Print() const { std::cout << "Base\n"; }
    virtual Base* Clone() const = 0;
};

class Derived : public Base
{
public:

    void Print() const { std::cout << "Derived\n"; }
    Derived* Clone() const { return new Derived(*this); }
};

class Container
{
private:
    std::vector<Base*> m_collection;
public:
    void Add(const Base& objectToAdd)
    {
        Base* copyOfBase = objectToAdd.Clone();
        m_collection.push_back(copyOfBase);
    }

    Base* GetObjectAtIndex(int index) const
    {
        return index < m_collection.size() ? m_collection.at(index) : NULL;
    }

    ~Container()
    {
        for (auto &obj : m_collection)
        {
            delete obj;
        }

        m_collection.clear();
    }
};

int main(int argc, const char* argv[])
{
    Container myContainer;

    Derived derivedObject;

    myContainer.Add(derivedObject);
    
    Base* retrievedObject = myContainer.GetObjectAtIndex(0);

    if (retrievedObject)
    {
        retrievedObject->Print();
    }

    return 0;
}