Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » Developing U++ » U++ Developers corner » Template class factory
Re: Template class factory [message #24392 is a reply to message #24391] Wed, 13 January 2010 15:37 Go to previous message
mdelfede is currently offline  mdelfede
Messages: 1307
Registered: September 2007
Ultimate Contributor
Well, quite interesting topic Smile

The definitive factory, thanx to Mirek know-how :

#ifndef _ClassFactory_ClassFactory_h_
#define _ClassFactory_ClassFactory_h_

#include <Core/Core.h>
using namespace Upp;

template<class T> class WithFactory
{
	private:
		typedef One<T> (*CreateFunc)();
		typedef VectorMap<String, CreateFunc>mapType;
		static mapType &classMap() { static mapType cMap; return cMap; }
		static VectorMap<String, String> &typeMap() { static VectorMap<String, String> tMap; return tMap; }
		template<class D> static One<T> __Create(void) { return One<T>((T *)new D); }
	public:
	
		template<class D> static void Register(const String &name)
		{
			classMap().Add(name, __Create<D>);
			typeMap().Add(typeid(D).name(), name);
		}
		static One<T> Create(const String &className) { return classMap().Get(className)(); }
		static T *CreatePtr(String const &className) { return classMap().Get(className)().Detach(); }
		static Vector<String> const &Classes(void) { return classMap().GetKeys(); }
		String const &IsA(void) { return typeMap().Get(typeid(*this).name()); }
		virtual ~WithFactory() {}
};

#define REGISTERCLASS(type) \
	INITBLOCK { \
	type::Register<type>(#type); \
}
#endif


and the sample usage :
#include "ClassFactory.h"

class Base : public WithFactory<Base>
{
};

class Derived : public Base
{
};

REGISTERCLASS(Base);
REGISTERCLASS(Derived);

CONSOLE_APP_MAIN
{
	One<Base> p1 = Base::Create("Base");
	One<Base> p2 = Base::Create("Derived");

	Cerr() << "p1 is a '" << p1->IsA() << "'\n";
	Cerr() << "p2 is a '" << p2->IsA() << "'\n";
	
	Base *ptr = Base::CreatePtr("Derived");
	Cerr() << "ptr  is a '" << ptr->IsA() << "'\n";
	delete ptr;
	
	Base *d = new Derived;
	Cerr() << "d  is a '" << d->IsA() << "'\n";
	delete d;

}
 
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Previous Topic: Helper for internazionalize arrays of literals
Next Topic: Polymorphic XMLizer
Goto Forum:
  


Current Time: Fri May 10 07:05:45 CEST 2024

Total time taken to generate the page: 0.02423 seconds