1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
| #include <iostream>
#include <map>
#include <memory>
#include <string>
template<class T>
class SingletonCRTP
{
SingletonCRTP(SingletonCRTP const& other) = delete;
SingletonCRTP& operator=(SingletonCRTP const& other) = delete;
public:
static T& instance() {return _instance;}
protected:
SingletonCRTP() {}
private:
static T _instance;
};
template<class T>
T SingletonCRTP<T>::_instance;
class Object
{
public:
virtual ~Object() {}
inline std::unique_ptr<Object> clone() const
{
return std::unique_ptr<Object>(virtClone());
}
private:
virtual Object* virtClone() const = 0;
};
class Tile : public Object
{
public:
typedef Object typeParent; // lu par le code de ObjectFactory
explicit Tile(int id) : _id(id) {}
~Tile() override {}
inline std::unique_ptr<Tile> clone() const
{
return std::unique_ptr<Tile>(virtClone());
}
inline int getId() const {return _id;}
private:
Tile* virtClone() const override
{
return new Tile(*this);
}
int _id;
};
class TileDeriv : public Tile
{
public:
typedef Tile typeParent; // lu par le code de ObjectFactory
TileDeriv(int id, int idBis) : Tile(id), _idBis(idBis) {}
~TileDeriv() override {}
inline std::unique_ptr<TileDeriv> clone() const
{
return std::unique_ptr<TileDeriv>(virtClone());
}
inline int getIdBis() const {return _idBis;}
private:
TileDeriv* virtClone() const override
{
return new TileDeriv(*this);
}
int _idBis;
};
template<class T>
class ObjectFactory;
template<>
class ObjectFactory<Object> : public SingletonCRTP<ObjectFactory<Object>>
{
friend class SingletonCRTP<ObjectFactory<Object>>;
private:
ObjectFactory<Object>() {}
~ObjectFactory<Object>() {}
public:
void add(std::string const& key, Object const& obj)
{
_mapFactory[key] = &obj;
}
std::unique_ptr<Object> construct(std::string const& key) const
{
Object const* tmp = _mapFactory.at(key);
return tmp->clone();
}
private:
std::map<std::string, Object const*> _mapFactory;
};
template<class T>
class ObjectFactory : public SingletonCRTP<ObjectFactory<T>>
{
friend class SingletonCRTP<ObjectFactory<T>>;
private:
ObjectFactory() : _objectFactoryParent(ObjectFactory<typename T::typeParent>::instance()) {}
~ObjectFactory() {}
public:
void add(std::string const& key, T const& specificObject)
{
_objectFactoryParent.add(key, specificObject);
_mapFactory[key] = &specificObject;
}
std::unique_ptr<T> construct(std::string const& key) const
{
T const* tmp = _mapFactory.at(key);
return tmp->clone();
}
private:
ObjectFactory<typename T::typeParent>& _objectFactoryParent;
std::map<std::string, T const*> _mapFactory;
};
int main()
{
ObjectFactory<Tile>& tileFactory = ObjectFactory<Tile>::instance();
ObjectFactory<TileDeriv>& tileDerivFactory = ObjectFactory<TileDeriv>::instance();
Tile tile(1);
TileDeriv tileDeriv(2, 3);
tileFactory .add("Tile 1", tile);
tileDerivFactory.add("TileDeriv 2-3", tileDeriv);
std::unique_ptr<Tile> toto = tileFactory .construct("TileDeriv 2-3");
std::unique_ptr<TileDeriv> titi = tileDerivFactory.construct("TileDeriv 2-3");
std::cout << "Id de toto : " << toto->getId() << "\n";
std::cout << "IdBis de titi : " << titi->getIdBis() << "\n";
return 0;
} |
Partager