Jump to content
  • Advertisement

Archived

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

stodge

Storing class names in a string?

This topic is 5743 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Is there any way in C++ to store the name of a class in C++, and then use that string to create a new instance of that class? For example, if I have in make believe pseudo-code:
class baseObject
{
};

class testObject: public baseObject
{
};

ClassName = "testObject";
obj = new ClassName(); 
Is this possible in anyway? Thanks http://www.stodge.net - the powerhouse in personal commentary [edited by - stodge on October 3, 2002 11:24:50 AM] [edited by - stodge on October 3, 2002 11:25:37 AM]

Share this post


Link to post
Share on other sites
Advertisement
Not directly, no. C++ does not support reflexion. You need to create a factory.


    
#include <map>
#include <string>

using namespace std;


class BaseObject
{
public:
virtual ~BaseObject() = 0 {}
};

class Factory
{
public:
typedef BaseObject* builder_t();
typedef std::map<string, builder_t*> builder_map_t;

BaseObject* Create( const std::string& name )
{
builder_map_t::iterator itor = builders.find( name );
if( itor == builders.end() ) return NULL;
return itor->second();
}

Factory& Register( const std::string& name, builder_t* fn )
{
builders[name] = fn; return *this;
}

Factory& Unregister( const std::string& name )
{
builders.erase( name ); return *this;
}
private:
builder_map_t builders;
};

class TestObject : public BaseObject
{
public:
~TestObject() {}
};

BaseObject* CreateTestObject() { return new TestObject; }

int main()
{
Factory fact;
fact.Register( "TestObject", CreateTestObject );


BaseObject* obj = fact.Create( "TestObject" );

delete obj;
}



Edit: fixed code so it would compile.

Documents [ GDNet | MSDN | STL | OpenGL | Formats | RTFM | Asking Smart Questions ]
C++ Stuff [ MinGW | Loki | SDL | Boost. | STLport | FLTK | ACCU Recommended Books ]


[edited by - Fruny on October 3, 2002 11:47:09 AM]

Share this post


Link to post
Share on other sites
Look up RTTI and type_info. They're standard C++ features. Beware that you usually have to manually enable RTTI--the default is disabled in MSVC (e.g.).

Edit: oops, didn't realize he also wanted to use it with a class factory. Well, maybe you could use type_info anyway; ok probably not. =)

[edited by - Stoffel on October 3, 2002 11:36:51 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by stodge
Awesome Fruny, thanks. I'll try to understand what you've written.



It's simple, really :

create a map (associative array) that associates string identifiers to a function that creates an object of the desired type. New names/functions are added to the map with Register(). Then when you want to create an object, take the passed string, look up the corresponding function in the map, call it and return the generated object.

Edit: note - I've fixed a few errors in the code above.

Documents [ GDNet | MSDN | STL | OpenGL | Formats | RTFM | Asking Smart Questions ]
C++ Stuff [ MinGW | Loki | SDL | Boost. | STLport | FLTK | ACCU Recommended Books ]


[edited by - Fruny on October 3, 2002 11:47:53 AM]

Share this post


Link to post
Share on other sites
Weird. I started a new project to try out some more ideas (taking it a step further) and I get lots of warnings like this:

c:\program files\microsoft visual studio\vc98\include\xtree(110) : warning C4786: 'std::_Tree,std::allocator >,std:air,std::allocator > const ,
msNetObject * (__cdecl*)(void)>,std::map,std::allocator >,msNetObject * (__cdecl*)(void),std::less,std::allocator > >,std::allocator* (__cdecl*)(void)> >::_Kfn,std::less,std::allocator > >,std::allocator >::const_iterator::_Inc' : identifier was truncated to '255' characters in the debug informat
ion


I've never seen this before. Any ideas what I'm doing wrong with VC6?

Thanks

[edited by - stodge on October 3, 2002 1:40:23 PM]

Share this post


Link to post
Share on other sites
It''s a harmless warning. You can disable it by adding #pragma warning(disable: 4786) to your code.

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!