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
   | #include <iostream>
#include <map>
#include <iterator>
#include <string>
 
using namespace std;
 
//la classe prototype
template <class T> class Prototype
{
	public:
	virtual ~Prototype(){}	
	virtual T* Clone() const =0 ;
};
 
//l'interface "Figure" 
class Figure : public  Prototype<Figure>
{
	public: 
	virtual void SeDessiner()=0;
};
 
class Carre : public Figure 
{
public:
	Figure* Clone() const ;
	void SeDessiner();
};
 
class Cercle : public Figure 
{
public:
	Figure* Clone() const ;
	void SeDessiner();
};
 
//La fabrique a proprement parler
template <class Object,class Key=string> class Factory
{
std::map<Key,Object*> m_map;
public:
 
	//La fonction qui va créer les objets
	Object* Create(const Key& key) const ;
 
	//Celle qui associe clé <=> prototype
	void Register(Key key,Object* obj);
};
 
 
 
Figure* Carre::Clone() const 
{
 return new Carre(*this);
}
 
void Carre::SeDessiner()
{
cout<<"Je suis un Carre"<<endl;
}
 
 
Figure* Cercle::Clone() const 
{ 
	return new Cercle(*this);
}
 
void Cercle::SeDessiner()
{
	cout<<"Je suis un Cercle"<<endl;
}
 
 
 
template <class Object,class Key> void Factory<Object,Key>::Register(Key key,Object* obj)
{
//si la clé n'est pas déja présente
		if(m_map.find(key)==m_map.end())
      	{
			//on ajoute l'objet dans la map
			m_map[key]=obj;
		}
//on pourrai détruire obj mais cette tache ne revient pas à la Register
}
 
template <class Object,class Key> Object* Factory<Object,Key>::Create (const Key& key) const 
{
		Object* tmp=0;
 
		typename std::map<Key, Object*>::const_iterator it=m_map.find(key);
 
		//si l'itérateur ne vaut pas map.end(),cela signifique que la clé à été trouvé     
		if(it!=m_map.end())
		{
			//donc on clone l'objet
	      	tmp=((*it).second)->Clone();
      	}
//on pourrai lancer une exeption au besoin
		return tmp;
}
 
 
 
int main(void)
{
 Factory<Figure> fac;
 
 fac.Register("Carre",new Carre);
 fac.Register("Cercle",new Cercle);
 
  Figure *c=fac.Create("Cercle");
  Figure *ca=fac.Create("Carre");
 
  c->SeDessiner();
  ca->SeDessiner();
 
  delete c;
  delete ca;
 
  return 0;
} | 
Partager