Skip to main content
GameDev.net gamedev.net
🔒 Locked

Object Factory problem...

Started by bodiddlie Jun 26, 2007 at 1:03 PM 1 replies 950+ views
Original Post
bodiddlie
bodiddlie
I'm trying to implement an object factory so that I can instantiate a object by just having the name of a class. I'm using a std::map to store a function pointer for creating a derived instance of a base class with the name as a key.

CBaseEntity* CreateTexturedSphere()
{
    return new TexturedSphere;
}

const bool registered = SceneManager::Instance()->RegisterEntity("textured_sphere", CreateTexturedSphere);

and the implementation of SceneManager::RegisterEntity

bool SceneManager::RegisterEntity(char* name, CreateEntityCallback CreateFn)
{
    return mCallbacks.insert(std::pair<char*, CreateEntityCallback>(name, CreateFn)).second;
}

then somewhere in the code I call this:

CBaseEntity* mPlanet;
mPlanet = SceneManager::Instance()->CreateEntity("textured_sphere");

and it gives me a seg fault. The backtrace of gdb tells me that the function being called is unknown. Here's the code for SceneManager::CreateEntity

CBaseEntity* SceneManager::CreateEntity(char* name)
{
    CallbackMap::iterator it = mCallbacks.find(name);

    return (it->second)();
}

I know there's no error checking here, I'll be putting that in later. When I step through this, it's not finding the function registered in the map. Any ideas what's happening here? -bodiddlie
http://gamesandgeeks.blogspot.com
CTar
CTar
Quote:
Original post by bodiddlie
I know there's no error checking here, I'll be putting that in later.

Seems like a pretty stupid idea considering it's while debugging it you need error checking the most.

Quote:
When I step through this, it's not finding the function registered in the map. Any ideas what's happening here?

A char pointer (char*) is NOT a string, it just some address to memory. So while "textured_sphere" and "textured_sphere" are the same are the same strings, when the map compares them it finds them to be different because their addresses are different.

The solution is to use a real string class like std::string (you could also just specify your own comparison function to the map, but I definitely don't recommend this).

What exactly is this system for? It seems to be a pretty bad idea to implement something like this in C++ unless it's for interfacing with a scripting language or something like that. Is there any reason the programmer only knows the string identifying the class and not the actual class?

Also who will delete the returned CBaseEntity pointer? Do you depend on the user to do it?
bodiddlie
bodiddlie
Quote:

Seems like a pretty stupid idea considering it's while debugging it you need error checking the most.


Even if I had error checking here, all it would do is handle the fact that it's returning std::map::end(). I'd still have the problem. That being said, you're right about using char*. I always forget I'm working with addresses. I've switched it to std::string and it's working perfectly.

The system will be used to load the entities from an xml file. I just have it set up this way for quick testing as I haven't implemented the xml parser just yet.

Thanks for the reply!

-bodiddlie
http://gamesandgeeks.blogspot.com

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.