Reputation: 1348
My program reads from a configuration file and instantiates several classes with the contents of two specific sections for each time.
To initialize Voice
class, I'd call:
initializeDomain ("voice", voice_config, voice_config_fields);
and Voice
should be initialized as:
Voice voice ( config, config_fields );
To do so, I programmed the following function:
void initializeDomain (string dom, map<string, string> & config, map<string, string> & config_fields)
{
if ( dom == "voice" ) {
Voice voice ( config, config_fields );
return voice;
} else if ( dom == "account" ) {
Account account (config, config_fields);
return account;
}
}
This is obviously not working, as the return type is variable, depending on the class that is instantiated. So, I tried to build a template that could address this need:
template <typename T>
T initializeDomain (string dom, map<string, string> & config, map<string, string> & config_fields)
{
if ( dom == "voice" ) {
T instantiated ( config, config_fields );
} else if ( dom == "account" ) {
T instantiated ( config, config_fields );
}
return instantiated; }
}
But it does not work either. How can I instantiate different classes in the template?
Upvotes: 2
Views: 847
Reputation: 21
If I understand your question correctly, I would suggest using a factory pattern to allow feeding in your various types and returns the desired instance. I hope that helps.
Upvotes: 2
Reputation: 175
It may not fit the question exactly without some assumptions, but with what we have to go on, I would have to agree with the factory pattern.
Good luck and please let us know how you resolved the issue?
Upvotes: 1
Reputation: 84239
This looks like classic application for Factory Design Pattern. Allocate instances dynamically and return by [smart] pointer:
class Base {};
class DerivedOne : public Base {};
class DerivedTwo : public Base {};
typedef std::unique_ptr<Base> BasePtr;
BasePtr createFoo( /* arguments */ ) {
BasePtr ptr; // initialized to nullptr
if ( ... ) ptr.reset( new DerivedOne );
else if ( ... ) ptr.reset( new DerivedTwo );
else ...
return ptr;
}
The usage for above setup is for polymorphic types, i.e. when you have a common interface to different implementations, so you would invoke virtual methods via pointer, like:
BasePtr base = createFoo( /* args */ );
base->callVirtualFunction( /* args */ );
What you are talking about is a bit strange. C++ is strongly-typed language, i.e. you can't store instances of unrelated types into same variable. The simple case you are describing looks like this:
std::string value = getInputSomewhere();
if ( value == "voice" ) {
Voice v( /* ctor args */ );
// do your voice stuff here
} else if ( value == "account" ) {
Account a( /* ctor args */ );
// do your account stuff here
} else {
// ...
}
So I don't really see what you are trying to accomplish with that template.
Upvotes: 2