2

Let's say I have a string with my class name inside:

mystring = "CDialogChild";

I would like to create an object of the type name written in my string. I'd like to do something like:

CDialogParent dlg = CDialogParent(mystring);

My new dlg is now created as type CDialogChild and I can use its methods:

dlg.mycdialogchild_method();
Hoornet
  • 1,398
  • 3
  • 18
  • 30
  • duplicate http://stackoverflow.com/questions/582331/c-is-there-a-way-to-instantiate-objects-from-a-string-holding-their-class-name – Maxim Krizhanovsky Jul 26 '11 at 14:07
  • Possible duplicate of http://stackoverflow.com/questions/1096700/c-instantiate-class-from-name? – useraged Jul 26 '11 at 14:08
  • "I can use its methods" - you can never use member functions that the type of your variable doesn't have. `CDialogParent` has no member function `mycdialogchild_method`. – Steve Jessop Jul 26 '11 at 14:11
  • But my dlg is not of the type CDialogParent! It's the type of CDialogChild and this one has CDialogChild – Hoornet Jul 26 '11 at 14:26
  • By the way, you don't need to prefix class names with "C". This is a Microsoft technique used to avoid naming conflicts with other code. So don't repeat their style and prevent yourself from clashing with their code. – Thomas Matthews Jul 26 '11 at 15:25
  • @Hoornet. You're mistaken about the type of your variable. `CDialogParent dlg = something` creates an automatic variable of type `CDialogParent`. You could instead do `CDialogParent *pdlg = something`, which could then point to an instance of `CDialogChild`. However, the *pointer* would still have type `CDialogParent*`, and you would have to convert that pointer to another type in order to use member functions of `CDialogChild` that are not in `CDialogParent`. C++ has static types, and the compiler enforces that you can only use the interface of the static type. – Steve Jessop Jul 26 '11 at 16:23
  • @Steve Yes! Of course! You are correct. It was my intention to do something like: DialogParent *pdlg = DialogChild; pdlg->DoModal(); // this method is included in all Dialogs – Hoornet Jul 27 '11 at 05:25

3 Answers3

1

There is nothing in C++ that will provide you such feature (called Reflection).

However, if your classes are of finite number, you can do some kind of mapping with some factories :

class IClassFactory // base interface
{ public: 
    virtual ~IClassFactory(){} 
}

template< class T >
class ClassFactory { 
/* whatever necessary here*/
public:

  T* create();
};


class ClassManager
{
public:

   void add( std::string name, IClassFactory* factory ) { m_map[name] = factory; }

   ACommonBaseClass* create( std::string class_name ) { return m_map[class_name]->create(); } // this line isn't correct but you get the idea

private:

   std::map< std::string, IClassFactory* > m_map;

};

Or something similar (this is written quickly).

Alternatively you could work with a scripting language that would allow Reflection, but that would add a whole layer to your application. Scripting languages that might be of interest for embedding with c++ : ChaiScript, Falcon, Lua, Python, AngelScript, MonkeyScript, Io, ...

Klaim
  • 67,274
  • 36
  • 133
  • 188
0

In general this is not possible within the language, since C++ is not a reflective language and it is statically typed.

As an alternative, you could consider hardcoding a collection of related, polymorphic types with a common base class into the program and writing a factory method that creates the desired concrete instance based on a runtime parameter.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
0

There is a design pattern for completing your objective: Factory. You will need to compare the class name and return the object:

class MyObject;

MyObject * creator(const std::string& object_name)
{
  return (object_name == "MyObject") ? new MyObject : 0;
}

The Factory pattern differs a little in that it uses pointers to a base class and returns instances of child classes.

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154