#include <iostream>
#include <unordered_map>
#include <string>

class Component
{
public:
	virtual Component* Clone() const = 0;
	virtual std::string ComponentType() const = 0;
};

class Player : public Component
{
public:
	Component* Clone() const
	{
		return new Player(*this);
	}
	
 	std::string ComponentType() const
	{
		return "PlayerComponent";
	}
};

class GameObject : public Component
{
public:
	Component* Clone() const
	{
		return new GameObject(*this);
	}
	
	std::string ComponentType() const
	{
		return "GameObjectComponent";
	}
};

class SomeContainer
{
private:
	std::unordered_map<std::string, Component*> m_components;

public:	
	void AddComponent(Component* theComponent)
	{
		if (m_components.find(theComponent->ComponentType()) == m_components.end())
		{
			m_components.insert(std::make_pair(theComponent->ComponentType(), theComponent));
		}
		else
		{
			std::cout << "I didn't add this " << theComponent->ComponentType();
			std::cout << " as I already have one" << std::endl;
		}
	}
};

int main() 
{
	auto someContainer = SomeContainer();
	auto aPlayer = new Player();
	
	someContainer.AddComponent(aPlayer);
	someContainer.AddComponent(new GameObject());
	someContainer.AddComponent(aPlayer->Clone());
	
	return 0;
}