Archived

This topic is now archived and is closed to further replies.

supagu

c++ factories

Recommended Posts

im trying to write a template factory class but some things just wont want to work: factory code:
template <class T>
class Factory;

class FactoryManager
{
public:
	static int RegisterFactory( Factory<class T>* const f )
	{
		classRegistery.insert( std::make_pair( classRegistery.size(), f ) );
		return (classRegistery.size() - 1);
	}

protected:
	typedef std::map< int, Factory<class T>* > Registery;

	static Registery classRegistery;
};

template <class T>
class Factory
{
public:
	Factory()
	{
		if( !bRegistered )
		{
			id = FactoryManager::RegisterFactory( this );
			bRegistered = true;
		}
	}
	
	static const int GetID()
	{
		return id;
	}
protected:
	static bool bRegistered;
	static const T registerThis;
	static int id;
};
 
example:
class Obj1 : public Factory<Obj1>
{
public:
	Obj1()
	{
	};
};

class Obj2 : public Factory<Obj2>
{
public:
	Obj2()
	{
	};
};
 
what this should do is register Obj1 and Obj2 in the FactoryManager and it should give Obj1 a static id so in future i can go: Factory* obj = FactoryManager::Create( Obj1::GetID() ); or Factory* obj = FactoryManager::Create( 0 ); the error visual studio gives me is:
error C2664: 'RegisterFactory' : cannot convert parameter 1 from 'class Factory<class Obj1> *const ' to 'class Factory<class T> *const '
 
[edited by - supagu on November 15, 2003 10:28:56 PM]

Share this post


Link to post
Share on other sites
You''re trying to have a pointer to one type point to an entirely different type.
There is an article here on gamedev that you can find in the ''featured articles'' section that covers writing factories in c++.
Oh, and the tag you''re looking for is source.

Share this post


Link to post
Share on other sites
What you want is a FactoryBase. The problem here is that you want to keep a list of all the Factory objects, but there are many different and incompatible Factory types since Factory is a template. Have a FactoryBase class that the Factory template inherits, and keep a list of those base pointers.

Peace,
Doc

Share this post


Link to post
Share on other sites
okay...

now all its is complaning about is my static int id

which i have in my cpp file as:


int Factory<class T>::id = 0;


and visual studio is giving me the following error:

Main.obj : error LNK2001: unresolved external symbol "protected: static int Factory<class Obj1>::id" (?id@?$Factory@VObj1@@@@1HA)


thats when i go to use the function like:

Obj1::GetID()

but if i comment like that out, i dont get the compiler error?

Share this post


Link to post
Share on other sites
You have 2 options:

1) Put the ID as a field in FactoryBase, or

2) Go with the templates:
quote:
Original post by supagu
which i have in my cpp file as:


Anything that is templatised must be in the header, not the cpp file. Put this in the header:

template<class T>
int Factory<T>::id = 0;



Image loads when I''m online!The following statement is true. The previous statement is false.
Shameless promotion:
FreePop: The GPL Populous II clone.

Share this post


Link to post
Share on other sites
okay i had some bugs there in my code...

its all working now except when i do:


class Obj1 : public Factory<Obj1>
{
public:
Obj1()
{
};
};


it doesnt call the factory constructor

as an Obj1 should be instantated

as my Factory template includes:
static const T registerThis;

and i do:

template<class T> const T Factory<T>::registerThis;
[source]

Share this post


Link to post
Share on other sites
Hmm. What I''ve found with GCC is that if you don''t try to access a field somewhere in your code it won''t get linked in. Perhaps this is the same. Try referring to the registerThis field somewhere somehow. Maybe a "touch" function that doesn''t actually do anything. I don''t think it matters where in the code you do this.

Share this post


Link to post
Share on other sites
yeah thats the problem, but still, i have to code in to access registerThis say in my main loop or on some code that will actually get run... which defeats the purpose :-/

if there a compiler option to force it to include it?

Share this post


Link to post
Share on other sites
yay it worked, hrmm, thought i tryied that b4 :-/

i got Create working also, but using a non static function, is there a way i can do it with a static function instead?

i guess when i register a class instead of mapping to a pointer of that class, map to a pair which points to the object and a static create function?

[edited by - supagu on November 15, 2003 12:24:22 AM]

Share this post


Link to post
Share on other sites