3

Possible Duplicate:
C++: instantiate class from name?

For example, if I have

string s = "myObject";

So how can I use that String s to make this one?

return new myObject();

I tried this one but it's quite silly and it's wrong

return new s();

Thank you

Community
  • 1
  • 1
Xitrum
  • 7,765
  • 26
  • 90
  • 126
  • What you're trying to do is hard in C++, at least for the general case. You might think about using a language that better supports this sort of operation. – Carl Norum Mar 27 '11 at 06:46
  • because i'm trying to use factory pattern, i know this problem can be solved by Java, but i'm learning c++ so i want to give it a try – Xitrum Mar 27 '11 at 06:50
  • @user552279 - That's your answer; Use the factory or registry pattern. You can find tons of examples with google. – Brian Roach Mar 27 '11 at 06:53
  • The factory pattern is just **one class responsible for creating/instatiating** your objects. So when you need to change it you will change only one class. – gideon Mar 27 '11 at 06:54
  • same question http://stackoverflow.com/questions/1096700/c-instantiate-class-from-name – Mark.Ablov Mar 27 '11 at 06:47

5 Answers5

10

You can create a simple factory and register the classes you want to be able to construct. This is a very light-weight sort-of reflection.

#include <map>
#include <string>

template <class T> void* constructor() { return (void*)new T(); }

struct factory
{
   typedef void*(*constructor_t)();
   typedef std::map<std::string, constructor_t> map_type;
   map_type m_classes;

   template <class T>
   void register_class(std::string const& n)
   { m_classes.insert(std::make_pair(n, &constructor<T>)); }

   void* construct(std::string const& n)
   {
      map_type::iterator i = m_classes.find(n);
      if (i == m_classes.end()) return 0; // or throw or whatever you want
      return i->second();
   }
};

factory g_factory;

#define REGISTER_CLASS(n) g_factory.register_class<n>(#n)

int main()
{
   using namespace std;

   REGISTER_CLASS(string);

   std::string* s = (std::string*)g_factory.construct("string");

   printf("s = '%s'\n", s->c_str());
   *s = "foobar";
   printf("s = '%s'\n", s->c_str());

   return 0;
}
Arvid
  • 10,915
  • 1
  • 32
  • 40
1

What you want is called virtual constructor (pattern). The availability of this feature in a language is not necessarily coupled to the language being interpreted or managed by a VM - it depends on how (and if at all) the information about types existing in a program (or library) is available at run time. This is not the case in "naked" C++ - but it can be implemented, as shown by Arvid, for example. The problem is that there is no standardized implementation of this feature, so everybody keeps re-inventing this again and again. To certain extent COM or it's platform independent counterpart XPCOM "standardize" this at component level.

Paul Michalik
  • 4,331
  • 16
  • 18
0

You cannot do that in c++, by design. In c++, there is a clear distinction between a type and an object, which are two very different entities of the language. You can thus only instantiate a type and get back an object, and decide to do so at compile time (c++ does not provide any kind of reflection system unlike c# or java).

However, you can use a factory / registry for the objects you want to instantiate that way.

wendazhou
  • 295
  • 2
  • 10
0

You'll need Reflection to do that. But C++ AFAIK doesn't support reflection.

Interestingly QT C++ Supports some kinda reflection. Look at the C# section for how its done there, and Javascript has one function to do this. Its called eval()

gideon
  • 19,329
  • 11
  • 72
  • 113
-2

It's not possible to do this with C++ since the code run on it's own. Only interpreted languages, such as PHP, or programs that are run through interpreters allows this kind of feature.

Shamim Hafiz - MSFT
  • 21,454
  • 43
  • 116
  • 176