How do I create a class from a string at runtime ?

T

TazaTek

Hello,

I've seen some vague references on how to do this a factory, but not
in enough detail to create one, or even know if it's what I need.

Essentially, I'll have one of about 5 classes that could be referenced
as a string (from a file).

I'm not 100% sure of the relationship between the classes, but I
suspect that they will not be derived from a base class, but in this
case there is not a reason not to either, if it makes a difference.

Any help in pointing me in the direction of taking a string and
instantiating an object at runtime would be greatly helpful.

Thanks

Matt
 
D

Daniel T.

TazaTek said:
I've seen some vague references on how to do this a factory, but not
in enough detail to create one, or even know if it's what I need.

Essentially, I'll have one of about 5 classes that could be referenced
as a string (from a file).

I'm not 100% sure of the relationship between the classes, but I
suspect that they will not be derived from a base class, but in this
case there is not a reason not to either, if it makes a difference.

Any help in pointing me in the direction of taking a string and
instantiating an object at runtime would be greatly helpful.

Base* newObject( const string& s )
{
Base* result = 0;
if ( s == "classA" )
result = new ClassA;
else if ( s == "classB" )
result = new ClassB;
return result;
}
 
T

TazaTek

Base* newObject( const string& s )
{
Base* result = 0;
if ( s == "classA" )
result = new ClassA;
else if ( s == "classB" )
result = new ClassB;
return result;

}

That makes sense.

Is there a way to implement this dynamically?

for example, if I later determined that I could have 100 classes
(instead of the 5 I mention previously) that could be used (not likely
as I'd re-design) and a case statement would become quite burdensome
to maintain.

I thought somewhere there was a Factory pattern (or some other
pattern) that could be used for this, but I can't seem to connect the
dots and get the dynamic situation that I want. I know this is
(fairly) common, but I'm drawing a blank.

Thanks

Matt
 
D

Daniel T.

TazaTek said:
That makes sense.

Is there a way to implement this dynamically?

I think the answer to that depends on the development environment rather
than the language.

for example, if I later determined that I could have 100 classes
(instead of the 5 I mention previously) that could be used (not likely
as I'd re-design) and a case statement would become quite burdensome
to maintain.

There are ways of avoiding the case statement. For example creating a
map where the key is the string and the value is an object of the
appropriate type (or a builder of an object of the appropriate type.)
Then you could do something like this:

class Builder {
public:
virtual Base* create() = 0;
};

class Factory {
map<string, Builder*> builders;
public:
void addBuilder( string s, Builder* b ) {
builders = b;
}
Base* build( string s ) {
base* result = 0;
map<string, Builder*>::iterator it = builders.find( s );
if ( it != builders.end() )
result = it->second->create();
return result;
}
};

With just a little bit of creativity, each of your 100 classes can have
a global object associated with it that automatically inserts itself
into the Factory as a builder of that class. In this way classes can be
added and removed from the system at link time without having to change
the Factory code. This doesn't really count as dynamic because it can
only be done during program construction though...

Frankly though, I don't see the point. The code that knows what string
to pass to the Factory could just as easily new the object it needs
directly since it obviously knows what the type of the object is.
(Unless of course, the string was input from outside the system.)
 
I

Ian Collins

TazaTek said:
That makes sense.

Is there a way to implement this dynamically?

for example, if I later determined that I could have 100 classes
(instead of the 5 I mention previously) that could be used (not likely
as I'd re-design) and a case statement would become quite burdensome
to maintain.

I thought somewhere there was a Factory pattern (or some other
pattern) that could be used for this, but I can't seem to connect the
dots and get the dynamic situation that I want. I know this is
(fairly) common, but I'm drawing a blank.
Look a bit deeper, the factory pattern is what you are after. One
simple solution is a map of function pointers or objects that create
instances of the required classes.
 
T

TazaTek

Frankly though, I don't see the point. The code that knows what string
to pass to the Factory could just as easily new the object it needs
directly since it obviously knows what the type of the object is.
(Unless of course, the string was input from outside the system.)

That is precisely my problem. The string is in the form of a URL, and
must be mapped to a class and method to invoke.

The example you give gives me some ideas on how to proceed, and filled
in a precious piece that I didn't find elsewhere. Thanks.

Looks like I just need to dig deeper into the Factory explainations.

Matt
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,273
Latest member
DamonShoem

Latest Threads

Top