How can I instantiate a class with it's name? read my text ahead...

Discussion in 'C++' started by babakandme@yahoo.com, Dec 12, 2007.

  1. Guest

    Hi everybody:D

    I've a string that contains the name of a class.
    I want to instantiate from that class:

    string strategyNameStr;
    Strategy * strategy;

    // All of the following classes are derived from Strategy.
    // and """ strategyNameStr """ contains the name of one of the
    following classes.
    // e.g.
    strategyNameStr = _T( "SimpleStrategy" );

    SimpleStrategy * simStrategy;
    MiddleStrategy * midStrategy;
    HighStrategy * highStrategy;

    How can I use """ strategyNameStr """ in the next line...
    strategy = new ?

    or
    Is there at all any solution?

    Thanks.
    , Dec 12, 2007
    #1
    1. Advertising

  2. wrote:
    > I've a string that contains the name of a class.
    > I want to instantiate from that class:
    >
    > string strategyNameStr;
    > Strategy * strategy;
    >
    > // All of the following classes are derived from Strategy.
    > // and """ strategyNameStr """ contains the name of one of the
    > following classes.
    > // e.g.
    > strategyNameStr = _T( "SimpleStrategy" );
    >
    > SimpleStrategy * simStrategy;
    > MiddleStrategy * midStrategy;
    > HighStrategy * highStrategy;
    >
    > How can I use """ strategyNameStr """ in the next line...
    > strategy = new ?
    >
    > or
    > Is there at all any solution?


    #define INSTANTIATE_BY_NAME(var, str, clazz) \
    if (str == #clazz) var = new clazz

    strategy = 0;
    INSTANTIATE_BY_NAME(strategy, strategyNameStr, SimpleStrategy);
    if (!strategy)
    INSTANTIATE_BY_NAME(strategy, strategyNameStr, MiddleStrategy);
    if (!strategy)
    INSTANTIATE_BY_NAME(strategy, strategyNameStr, HighStrategy);

    or something like that.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Dec 12, 2007
    #2
    1. Advertising

  3. Pete Becker Guest

    On 2007-12-12 15:48:47 -0500, "Victor Bazarov" <> said:

    >
    > #define INSTANTIATE_BY_NAME(var, str, clazz) \
    > if (str == #clazz) var = new clazz
    >


    You don't need that Java-esque ugliness of misspelling class. The
    preprocessor doesn't care about keywords.

    --
    Pete
    Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
    Standard C++ Library Extensions: a Tutorial and Reference
    (www.petebecker.com/tr1book)
    Pete Becker, Dec 12, 2007
    #3
  4. Pete Becker wrote:
    > On 2007-12-12 15:48:47 -0500, "Victor Bazarov"
    > <> said:
    >>
    >> #define INSTANTIATE_BY_NAME(var, str, clazz) \
    >> if (str == #clazz) var = new clazz
    >>

    >
    > You don't need that Java-esque ugliness of misspelling class. The
    > preprocessor doesn't care about keywords.


    My editor does.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Dec 12, 2007
    #4
  5. Guest

    Re: How can I instantiate a class with it's name? read my textahead...

    Hi,
    thaks for the helps, but consider here:
    The solution is somehow """HardCoding"""...


    // Manager.h
    typedef map< string, SStrategy * > SStrategyPool;
    ....
    SStrategyPool SSPool;

    // Manager.cpp
    Manager::SomeFunction()
    {
    SStrategyPool::const_iterator iter;

    // FlyWeighy pattern
    iter = SSPool.find( strategyNameStr );

    // if the strategy has not been added to the pool
    if( iter == SSPool.end() )
    {

    /
    *==============================================================================
    Actually the problem is here, as you see, it is difficult to use some
    "HardCoded" code here.
    I mean the number of strategys may increase too much...
    and it's not nice to use "HardCoding..."...
    ==============================================================================*/
    // sStrategy = new ...?

    // Add the new Strategy to the pool
    SSPool.insert( strategyNameStr, sStrategy );

    // call the desired SStrategy->DoIt();
    sStrategy->DoIt();

    }
    else
    {
    // Use the old Added Strategy to the pool
    // call the desired SStrategy->DoIt();
    ( iter->second )->DoIt();
    }
    }
    , Dec 12, 2007
    #5
  6. Pete Becker Guest

    On 2007-12-12 16:42:05 -0500, "Victor Bazarov" <> said:

    > Pete Becker wrote:
    >> On 2007-12-12 15:48:47 -0500, "Victor Bazarov"
    >> <> said:
    >>>
    >>> #define INSTANTIATE_BY_NAME(var, str, clazz) \
    >>> if (str == #clazz) var = new clazz
    >>>

    >>
    >> You don't need that Java-esque ugliness of misspelling class. The
    >> preprocessor doesn't care about keywords.

    >
    > My editor does.
    >


    Sigh. Yet another "expert" on how people should write code. <g>

    --
    Pete
    Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
    Standard C++ Library Extensions: a Tutorial and Reference
    (www.petebecker.com/tr1book)
    Pete Becker, Dec 12, 2007
    #6
  7. Pete Becker wrote:
    > On 2007-12-12 16:42:05 -0500, "Victor Bazarov"
    > <> said:
    >> Pete Becker wrote:
    >>> On 2007-12-12 15:48:47 -0500, "Victor Bazarov"
    >>> <> said:
    >>>>
    >>>> #define INSTANTIATE_BY_NAME(var, str, clazz) \
    >>>> if (str == #clazz) var = new clazz
    >>>>
    >>>
    >>> You don't need that Java-esque ugliness of misspelling class. The
    >>> preprocessor doesn't care about keywords.

    >>
    >> My editor does.
    >>

    >
    > Sigh. Yet another "expert" on how people should write code. <g>


    LOL

    You and your duplicities! Did you mean that I'm the "expert" or
    that the editor is?

    I don't mean I have an editor who tells me how to write (I guess
    you had one when you published your "Extensions", perhaps he/she
    was too eager to edit, eh?). I actually meant the text editor
    with syntax highlighting that makes "class" to show in bold type,
    which I don't care for in that context.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Dec 12, 2007
    #7
  8. Pete Becker Guest

    On 2007-12-12 17:57:49 -0500, "Victor Bazarov" <> said:

    > Pete Becker wrote:
    >> On 2007-12-12 16:42:05 -0500, "Victor Bazarov"
    >> <> said:
    >>> Pete Becker wrote:
    >>>> On 2007-12-12 15:48:47 -0500, "Victor Bazarov"
    >>>> <> said:
    >>>>>
    >>>>> #define INSTANTIATE_BY_NAME(var, str, clazz) \
    >>>>> if (str == #clazz) var = new clazz
    >>>>>
    >>>>
    >>>> You don't need that Java-esque ugliness of misspelling class. The
    >>>> preprocessor doesn't care about keywords.
    >>>
    >>> My editor does.
    >>>

    >>
    >> Sigh. Yet another "expert" on how people should write code. <g>

    >
    > LOL
    >
    > You and your duplicities! Did you mean that I'm the "expert" or
    > that the editor is?


    Whoops, sorry: I meant the editor.

    >
    > I don't mean I have an editor who tells me how to write (I guess
    > you had one when you published your "Extensions", perhaps he/she
    > was too eager to edit, eh?).


    No, actually, the copy editors on my book were terrific. I learned a
    lot, and the book is much better for it.

    > I actually meant the text editor
    > with syntax highlighting that makes "class" to show in bold type,
    > which I don't care for in that context.
    >


    Yes, I knew that.

    --
    Pete
    Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
    Standard C++ Library Extensions: a Tutorial and Reference
    (www.petebecker.com/tr1book)
    Pete Becker, Dec 12, 2007
    #8
  9. ManicQin Guest

    Re: How can I instantiate a class with it's name? read my textahead...

    dont you prefer a factory?

    class strategyBuilder{
    public:
    static strategy* function buildStrategy(string objName)
    {
    if (objname == "sim")
    return static_cast<strategy*>(new SimpleStrategy());
    else if (objname == "mid")
    return static_cast<strategy*>(new MiddleStrategy());

    return NULL;
    }
    or something like that.

    you could use it in the form of class/global function and you would
    have to worry about pesky macro bugs.
    ManicQin, Dec 13, 2007
    #9
  10. Guest

    Re: How can I instantiate a class with it's name? read my textahead...

    Yeah my Man:>
    thanks...

    Actually first I didn't want to use any HardCoding...
    But now I see, here the FactoryMethod Pattern works...

    Once again, thank you in advance...
    , Dec 13, 2007
    #10
  11. Ondra Holub Guest

    Re: How can I instantiate a class with it's name? read my textahead...

    On 12 Pro, 22:44, wrote:
    > Hi,
    > thaks for the helps, but consider here:
    > The solution is somehow """HardCoding"""...
    >
    > // Manager.h
    > typedef map< string, SStrategy * > SStrategyPool;
    > ...
    > SStrategyPool SSPool;
    >
    > // Manager.cpp
    > Manager::SomeFunction()
    > {
    > SStrategyPool::const_iterator iter;
    >
    > // FlyWeighy pattern
    > iter = SSPool.find( strategyNameStr );
    >
    > // if the strategy has not been added to the pool
    > if( iter == SSPool.end() )
    > {
    >
    > /
    > *==============================================================================
    > Actually the problem is here, as you see, it is difficult to use some
    > "HardCoded" code here.
    > I mean the number of strategys may increase too much...
    > and it's not nice to use "HardCoding..."...
    > ==============================================================================*/
    > // sStrategy = new ...?
    >
    > // Add the new Strategy to the pool
    > SSPool.insert( strategyNameStr, sStrategy );
    >
    > // call the desired SStrategy->DoIt();
    > sStrategy->DoIt();
    >
    > }
    >
    > else
    > {
    > // Use the old Added Strategy to the pool
    > // call the desired SStrategy->DoIt();
    > ( iter->second )->DoIt();
    >
    > }
    > }


    You can create for example some map of functions, which create
    instances. Map may have as key text, which identifies the class. Then
    you can add to this map many many different functions to create
    instances.

    If you need for every instance constructor with different parameters,
    you can still achieve the above functionality - instead of storing
    functions you can store instances of some building classes.

    struct BaseClass
    {
    // ...
    };

    struct Builder
    {
    virtual ~Builder() { }
    virtual BaseClass* operator()() = 0;
    };

    typedef
    std::map<std::string, Builder> BuilderMap;

    // adding new builder
    struct SpecializedClass1: public BaseClass
    {
    SpecializedClass1(int, double);
    };

    struct SpecializedClass1Builder: public Builder
    {
    SpecializedClass1Builder(int i, double d)
    : i_(i),
    d_(d)
    {
    }

    virtual BaseClass* operator()()
    {
    return new SpecializedClass1(i_, d_);
    }
    };

    BuilderMap bm;
    bm.insert(std::make_pair("SpecializedClass1",
    SpecializedClass1Builder(2, 10.3)));
    Ondra Holub, Dec 13, 2007
    #11
  12. James Kanze Guest

    Re: How can I instantiate a class with it's name? read my textahead...

    On Dec 12, 10:42 pm, "Victor Bazarov" <> wrote:
    > Pete Becker wrote:
    > > On 2007-12-12 15:48:47 -0500, "Victor Bazarov"
    > > <> said:


    > >> #define INSTANTIATE_BY_NAME(var, str, clazz) \
    > >> if (str == #clazz) var = new clazz


    > > You don't need that Java-esque ugliness of misspelling class. The
    > > preprocessor doesn't care about keywords.


    > My editor does.


    I don't believe it. I've never seen an editor that wouldn't
    allow you to write just about anything. Do you mean it colors
    it wrong, or that it indents incorrectly afterwards? (In the
    latter case, of course, I'd wonder about the editor. All of the
    various editors I've used for C++ know about the preprocessor,
    and don't take macros into account for indenting.)

    Or did you mean editor in the human sense: someone who reads
    your code and corrects possible errors? Because human readers
    do care about keywords---the presence of class in the macro will
    immediately suggest a keyword to them, and probably cause some
    confusion. Of course, for human readers, clazz isn't any
    better; what you probably want is classname, or something like
    that. (In the places I've worked, of course, classe or Klasse
    would also work very well. A small advantage of being in a
    non-English speaking environment:).)

    Of course, any human editor would reject the code anyway, as
    unnecessary and improper use of a macro, when better solutions
    exist without the macro. The standard solution here is to use
    some sort of map, mapping the name to a factory method (or a
    factory interface). The map can be initialized in one of two
    ways:

    -- Dynamically, by initializers of static data. The author of
    each class arranges for a static instance of something which
    inserts his factory method or factory class into the
    map---I'll usually map to a pointer to a factory interface,
    with a constructor which does the registration; each class
    derives from the interface, providing the necessary
    function, and defines a static instance of its derived
    class.

    Of course, in this case, the map itself should be a
    singleton, to avoid order of initialization issues with it.

    I've even used this method with dynamic linking: when the
    lookup in the map failed, I derived the name of a dynamic
    object (.dll or .so, depending on the system) and tried to
    load it, then tried again in the map. If loading it loaded
    a static instance of the factory object, the second lookup
    would find the factory object. In this case, you can even
    find classes that weren't written yet when the program was
    installed.

    Of couse, you don't want to do this unless it's necessary.

    -- Statically, using a simple array of struct's:

    struct FactoryMapEntry
    {
    char const* className ;
    Base* (* factoryMethod)() ;
    } ;

    This has the advantage of simplicity, and avoids any issues
    of order of initialization, but it does mean that you have
    to write the initialization of the map in C++, compile it,
    and link it into your code. Or rather, someone or something
    has to write it; I imagine that in most cases, you'd
    generate it automatically by means of a shell script
    invoked from the makefile. Supposing, of course, some well
    defined naming convention for the factory methods (e.g.
    createXXX for class XXX---or maybe create< XXX >(), with an
    appropriately defined function template).

    For lookup, of course, std::find_if with an appropriate
    predicate will do the trick nicely.

    This method means that once (statically) linked, the
    available classes cannot change, and the complete map is
    available everywhere during initialization of static
    objects.

    I can't remember using this for factory methods, but I do it
    often enough for other things that I've a generic template
    to automatically generate the table entries and the
    necessary predicate for std::find_if.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Dec 13, 2007
    #12
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. ad
    Replies:
    3
    Views:
    317
    MattC
    May 12, 2005
  2. BogusException
    Replies:
    6
    Views:
    12,810
    BogusException
    Jul 18, 2006
  3. David Mitchell

    Can't instantiate class

    David Mitchell, Nov 6, 2005, in forum: Python
    Replies:
    0
    Views:
    314
    David Mitchell
    Nov 6, 2005
  4. Colin Mc Mahon

    Instantiate class within a class

    Colin Mc Mahon, Aug 12, 2004, in forum: ASP General
    Replies:
    2
    Views:
    175
    Colin Mc Mahon
    Aug 14, 2004
  5. Ben Harper
    Replies:
    9
    Views:
    100
    Patrick Spence
    Mar 8, 2007
Loading...

Share This Page