0

I am playing with some kind of shared object framework. It is using nlohmann::json to provide message passing and configuration and loads message handlers and datasources depending of the json config.

As I am using value classes, which all derive from a base class Value, I would like to allow all devs to create their own value classes within the lib. Therefore I need a mechanism to assign such a value onto a json object.

But how can I achieve this if I am only using pointers to the base class?

using json = nlohmann::json;

class Base
{
 public:
  Base () :str("Hurray") { };
 private:
  // const std::string() { return str; }
  std::string str;
};


class Derived1 : public Base
{
 public:
  Derived1() { myInt = 1; };
 public:
  int myInt;
};


void to_json(json& j, const Derived1& p) {
  j = json{{"Derived1", p.myInt}};
}

void from_json(const json& j, Derived1& p) {
  j.at("name").get_to(p.myInt);
}

int main(int argc, char* argv[]) {

  json myJ;
  Derived1 D1;
  myJ["D1"] = D1;
  std::cout << "myJ: " << myJ.dump() << std::endl;

  std::shared_ptr<Base> pointer = std::make_shared<Derived1>();
  json DerivedJson;
  //  DerivedJson["D1"] = *pointer;
  //  std::cout << "myJ" << DerivedJson.dump() << std::endl;
}

(Example also on https://github.com/Plurax/SOjsonassign)

One further question: My code is currently using an own string wrapper, which derives from Baseclass. I used to derive from a template Base which provides "asString", returning my string class, as its not available in the base class.

The only reason for the own string class is to provide a generic value interface. Is there another way to get a generic interface?

1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
Plurax
  • 44
  • 6

1 Answers1

2

You can create a virtual json tojson() const; function to base, then override that in your derived classes. Then, rather than using *pointer, call pointer->tojson(). The implementation in the classes can call the global to_json function, or the global function can call the one in the class.

1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
  • Omg thx, simple as that oO. An additional problem is that I dont understand how to construct a value which I can use as replacement within an existing object. I assumed to create a conversion (e.g. via operator int()), but this will break the return type of the suggested const method, not being a json key, value pair. (my UseCase is replacing a string value within a message with whatever Value is returned for example from a datasource (which is then a class derived from base)). I will adapt the example code on Github later to explain. – Plurax Oct 01 '18 at 18:58
  • Ok - again simple: Assign the desired content within the virtual override function and the assignment is neutral as the return type is always a json. This also allows wrapping own value type by assigning the standard ones (complex types can call to_json for convenience...) – Plurax Oct 02 '18 at 06:55