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));
3
  • You should use Class Factory pattern. Commented Oct 23, 2013 at 14:58
  • Do you just want to read which type to instantiate from the file or the entire definition? Commented Oct 23, 2013 at 14:59
  • another: stackoverflow.com/questions/19036462/… Commented Oct 23, 2013 at 15:01

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

5 Comments

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.
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
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.
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.
Thanks for the edit. Now that's an answer I can upvote.
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)

5 Comments

Not quite as "magical" as what I think OP is looking for, but a good workable solution nonetheless.
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.
@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?
The source code does not respect the open closed principle
@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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.