2

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?

4

3 回答 3

2

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.

于 2012-11-07T17:50:39.200 回答
2

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;
}

Edit 0:

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.

于 2012-11-07T17:56:44.313 回答
1

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?

于 2012-11-14T21:30:43.157 回答