1

I'm try to read a type from a text file and create an instance of it. for example

class MyType {
    public:
          MyType() {}
          ~MyType() {}     
};

char* type = "MyType";
type object = type(); 

I know this isn't correct but I think it explains what i'm trying to do pretty good. I am asking if there is a way to do it and how? I know there is a way to covert a type into a string via typeid(Type).name(); but is there a way to reverse this? meaning converting a string to a type.

thanks for reading :).

edit: if you still don't get it. what i want can be done in c# like this

var myObj = Activator.CreateInstance(Type.GetType(namespaceName + className));
Amit Hendin
  • 87
  • 1
  • 8

2 Answers2

3

You have to use a the design pattern factory

For those below, who want a source code, there is a quick and dirty factory. It uses c++11, it is not const-correct and has a basic support for arguments for the constructor, as long as they are all the same through creation function

#include <iostream>
#include <functional>
#include <memory>
#include <map>

template<class key,class Base,class ...Args> class Factory
{
  using creator = std::function<std::unique_ptr<Base>(Args...)>;
  std::map<key,creator> m;  
public:
  void registerF(key s,creator c)
    {
      m[s]=c;
    }

  std::unique_ptr<Base> operator()(key s,Args... a) 
    {
      return m[s](a...);
    }
};

struct A{virtual void foo()=0;};
struct B1 : A{virtual void foo(){std::cout<<"B1"<<std::endl;}};
struct B2 : A{virtual void foo(){std::cout<<"B1"<<std::endl;}};

template <class T> std::unique_ptr<T> creater()
{
  return std::unique_ptr<T>(new T());
}

int main() {
  Factory<std::string,A> f;
  f.registerF("B1",&creater<B1>);
  f.registerF("B2",&creater<B2>);
  auto p=f("B1");
  p->foo();

  return 0;
}

Edit : if you try to instanciate an class with a string that is not registered, you'll get an exception bad_function_call because map's operator[] will a empty std::function and call it.

Davidbrcz
  • 2,335
  • 18
  • 27
  • 1
    This answer would be much improved if it provided source code so that people don't have to follow a link to get an answer. – John Dibling Oct 23 '13 at 15:07
  • I hate providing source code. There are several ways to achieve a Factory (clone, using free functions). You can do something simple and something much more complicated with variadic emplates ad other stuff... The best way to let him improve himself is to give him the name of the technique and let him do the rest – Davidbrcz Oct 23 '13 at 15:11
  • 1
    One of the goals of SO is to be a one-stop-shop for canonical answers to programming questions. That's kind of hard to do by providing only hints, buzzwords and links to other sites. SO is intended to be a *primary source* of information -- not a place where you can find links to primary sources. Look around the most upvoted answers on SO and you'll find a common pattern emerge: high level of detail, and complex ideas described in source code. – John Dibling Oct 23 '13 at 15:18
  • Consider also that the semi-official policy on SO is that link-only answers are to be flagged and removed. Links aren't answers -- they're just links. Meta discussion [here](http://meta.stackexchange.com/questions/92505/should-i-flag-answers-which-contain-only-a-link-as-not-an-answer). – John Dibling Oct 23 '13 at 15:53
  • Thanks for the edit. Now *that's* an answer I can upvote. – John Dibling Oct 23 '13 at 15:55
0

With a factory for example:

class MyBase {};
class MyTypeA : public MyBase {};
class MyTypeB : public MyBase {};

std::shared_ptr< MyBase > make_instance( std::string type )
{
    if( type == "MyTypeA" )
        return std::make_shared< MyTypeA >();
    else
        return std::make_shared< MyTypeB >();
}

(You'll need some includes like <memory> I think)

wal-o-mat
  • 7,158
  • 7
  • 32
  • 41
  • Not quite as "magical" as what I think OP is looking for, but a good workable solution nonetheless. – John Dibling Oct 23 '13 at 15:29
  • Côme David and wal-o-mat, thank you for your answers but a factory does not suite my needs since it would require me to hard-code every class. I need to be able to just inherit from a base class without adding additional code to a factory or a make function. i need to covert the string to a type not check the string and choose a type. – Amit Hendin Oct 23 '13 at 15:29
  • @AmitHendin: What you're asking for is impossible in C++. At least, impossible without some awfully clever code, and even that clever code is going to look something like this in its guts. Why do you think you need this? – John Dibling Oct 23 '13 at 15:38
  • The source code does not respect the open closed principle – Davidbrcz Oct 23 '13 at 15:54
  • @JhonDibling I am building a tool for creating games in which the user of the tool will be able to add classes of his own and attach them to game nodes. I need this because i want to be able to save all of the users work into an xml file, and that includes each game node and it's attached classes. Therefore i need to write the types of these classes in the text of the xml file so i can create an instance of them to attach to the game node apoun reading the xml file. – Amit Hendin Oct 23 '13 at 18:41