2

I'm trying to use the value stored in an std::string to call a class instance of the same name, for example:

class myClass{int x;}

myClass hello;
std::string myString = "hello";

And then by doing this:

myClass* pleaseWork = myString*;

I'm hoping I can then do this:

std::cout << pleaseWork&.x;

I'm just wondering if this actually is possible, or if there's a keyword like

changeToClass(<string>, <classToBeTurnedInto>)

Thank you!

EDIT

Sorry if I didn't make it too clear, but what I'm trying to do is call a class whose name is stored in a string - so if myString contains "hello" I'm trying to call a class called "hello" by using the actual string. The practical use of this involves passing classes of class1 to classes of class2, but only knowing which classes to pass on by reading them from a file (which can only be read as char[] or std::string).

A bit like this, which I'm not sure how to do in C++.

Community
  • 1
  • 1
otah007
  • 505
  • 1
  • 4
  • 17

3 Answers3

4

Getting a variable or function by its name during runtime is in general not possible in standard C++.

However, you may be interested in dynamic linking and dynamic loading facilities.

On Linux, and some other Posix systems, you could consider using dlopen and dlsym. Read carefully dlopen(3) man page. The dlsym-ed names should usually be declared extern "C" to avoid name mangling ....

Read the c++ dlopen mini howto.

With C++11 read also about type_info, bad_cast, dynamic_cast, RTTI ...

reflection and type introspection are useful, but they are not very well supported in C++ (more possible in Java). Look also inside the poco library, and Qt meta object protocol....

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
4

It's perfectly possible to map a string to a class:

std::map<std::string, MyClass*> map;

and then look the string up in the map. The issue is how the pointer to the object gets into the map. You have to initialize the map by hand; more importantly, you have to ensure the lifetime of the object, being sure to remove it from the map before it is destructed.

In many cases, you can make all of your use of the object go through the map. In such cases, you can use a

std::map<std::string, MyClass> map;

(without the pointer): objects are constructed directly into the map, and are destructed by calling erase on the map. (This is, in a way, another type of dynamic allocation. Except that instead of pointers, you use strings to address the objects.)

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • @BasileStarynkevitch Of course. That's what he wants. At least from what I understand; he doesn't express himself that well. Alternatively, if he wants to create new instances of a type dependent on the string, he needs a map to factory functions. – James Kanze Oct 22 '13 at 08:45
  • Yes, that is exactly what I want (if I understand the answer correctly). However I have found my own solution that I think will work - make a variable of the class called 'name' that you can compare too (as long as class.name is equal to the name of the class instance). – otah007 Nov 08 '13 at 19:11
3

You could use an object factory pattern solution.

There is not really a standard way of implementing this in C++, but essentially you would create a static ObjectFactory method which would take as a parameter the name of a class. This method will look for a matching class definition, instantiate a class object, and return a pointer to it.

Simple example:

class ObjectFactory 
{
public:
    static MyBaseClass *ObjectFactory::createObject(std::string className);
};

MyBaseClass *object = ObjectFactory::createObject("SomeClassName");

If you don't have a common base class, you could simply return void * and cast it to your actual class pointer. There are more clever methods as well, using C++ features like smart pointers and templates. The details of your implementation would depend on your specific requirements.

This topic has been covered a number of times here on SO. See discussion in related questions here, and here, for example.

You can also Google "c++ factory pattern" for many more examples.

Community
  • 1
  • 1
Chris Olsen
  • 3,243
  • 1
  • 27
  • 41