-1

The idea is to create object at runtime in C++.

The input for this creation is going to be a json file. For example

{
  "pi": 3.141,
  "happy": true,
  "name": "Niels",
  "nothing": null,
  "answer": {
    "everything": 42
  },
  "list": [1, 0, 2],
  "object": {
    "currency": "USD",
    "value": 42.99
  }
}

What are the options to do this in C++? Can boost help on this?

cateof
  • 6,608
  • 25
  • 79
  • 153
  • 4
    You can't create classes at runtime. –  Jun 19 '17 at 11:26
  • 1
    So you want to create classes or objects at runtime ? One is easy (objects), the other is AFAIK impossible (classes). If you want to parse JSON with boost, you can use [this](http://www.boost.org/doc/libs/1_55_0/doc/html/property_tree.html) – nefas Jun 19 '17 at 11:27
  • 1
    It is impossible to actually create new classes, but your question did remind me of an interesting talk by Sean Parent, [Runtime Polymorphism](https://www.youtube.com/watch?v=QGcVXgEVMJg) – AndyG Jun 19 '17 at 11:56

2 Answers2

7

You can't do (define classes at runtime) that in standard C++, because a class has some code associated to it (at least, implicit constructors and destructors, and very often member functions, and very often has some vtable, generated by the compiler, pointing to code).

Your JSON parsing library (e.g. jsoncpp) will provide a type representing arbitrary JSON objects (in braces).

On some operating systems, you could load a plugin (containing code) at runtime; on Linux and POSIX use dlopen(3) but beware of name mangling (see C++ dlopen Mini-HowTo). The plugin is a shared object that you need to compile specifically as position-independent code. Several framework libraries (Qt, POCO, Boost DLL ...) provide common abstractions to load plugins, ...

You could even (I did that in MELT, on Linux) generate some C++ code on the fly at runtime in some temporary file, compile that temporary file into some temporary plugin, and load that plugin .... all this in the same process.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • I'm gonna add relevant part of my answer as a FWIW-comment: "You can create a type which values are "dynamic enough" to mimic something similar, like holding/representing multiple types. This is [what boost does](http://www.boost.org/doc/libs/1_64_0/doc/html/property_tree/parsers.html#property_tree.parsers.json_parser)." This approach would be alternative to injecting a "compiled type". One could also explore how C# implements generic types, but I guess they rely on IL, but there is a support for dynamically created type. – luk32 Jun 19 '17 at 11:42
  • 1
    @lik32: This is what [Michael Roy's answer](http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html) suggests. However, the OP is *parsing* JSON, and any JSON parser needs to represent JSON objects (or be event based) – Basile Starynkevitch Jun 19 '17 at 11:47
1

You could do this, or something close to this (i'm simplifying):

class VariableClass
{
private:
   typedef map<string, boost::any> MembersMap;

   string objectType;  // a label, defined at parsing... 
                       // could be an ID, but then you'd already know 
                       // the members to expect, and could use a 'regular' class.
   MembersMap members;

... etc...
   boost::any& operator [](const std:string& s) ( return members[s]; }
};

This is oversimplified, but should do what you want. You may want to replace boost::any with std::variant, or a custom specialized template class holding the types you want, which could also be determined at runtime from the json.

[edit] I've added a variable 'objectType'.

Michaël Roy
  • 6,338
  • 1
  • 15
  • 19
  • 3
    You've defined a class which contains a map, and provides a function to retrieve things from the map. How is this any better than just using a map? – Chris H Jun 19 '17 at 11:43
  • This class could of course provide more functionality as needed... We have no idea what the OP really wants to do with the data. He could also add a label to the class. Which I'll add now, to clarify. – Michaël Roy Jun 19 '17 at 11:53