#include <iostream>
#include <functional>
#include <unordered_map>
#include <vector>
#include <memory>

// Gemeinsame Basisklasse
class Base {
  public:
  	// Virtueller Destruktor
  	virtual ~Base () {}
    virtual void test () = 0;
};
// Abgeleitete Klassen
class Derived1 : public Base {
  public:
  	virtual ~Derived1 () { std::cout << "Derived1::~Derived1\n"; }
    virtual void test () { std::cout << "Derived1::test\n"; }
};
class Derived2 : public Base {
  public:
  	virtual ~Derived2 () { std::cout << "Derived2::~Derived2\n"; }
    virtual void test () { std::cout << "Derived2::test\n"; }
};

// Zuordnung (map) ID->Factory-Funktion
std::unordered_map<int, std::function<std::unique_ptr<Base> ()>> factories {
	{ 1 , []() { return std::unique_ptr<Base> (new Derived1); }},
	{ 42, []() { return std::unique_ptr<Base> (new Derived2); }}};

std::vector<std::unique_ptr<Base>> getObjects (std::vector<int> input) {
	// Erzeugte Objekte
	std::vector<std::unique_ptr<Base>> objects;
	
	for (int i : input) {
		// Suche Factory-Funktion...
		auto f = factories.find (i);
		if (f != factories.end ())
			// Rufe Factory-Funktion auf, erstelle Objekt, speichere in "objects"
			objects.push_back ((f->second) ());
		else
			std::cout << "Unbekannte ID " << i << std::endl;
	}
	return objects;
}


int main () {
	// Angenommen, das hier ist zur kompilezeit nicht bekannt (Dateieingabe o.ä.); enthält Liste an ID's, von denen Objekte angelegt werden sollen
	std::vector<int> input { 42, 1, 1, 42, 3, 1 };
	auto objects = getObjects (std::move (input));
	
	// Rufe virtuelle Funktion auf Objekten auf
	for (auto& obj : objects)
		obj->test ();
		
	// unique_ptr löscht Objekte hier
}

