I want to deserialize JSON file to an object(class) using C++. I've looked at rapidjson library and I made each class have a deserialize method with the root as parameter, so it can deserialize itself. It looks like this:
void PoliceOfficer::Deserialize(rapidjson::Value& root)
{
if (root.IsObject())
{
if (root.HasMember("name"))
{
if (root["name"].IsString())
{
name = root["name"].GetString();
}
}
if (root.HasMember("maxHealth"))
{
if (root["maxHealth"].IsNumber())
{
maxHealth = (float)root["maxHealth"].GetDouble();
}
}
if (root.HasMember("skills"))
{
rapidjson::Value& skills = root["skills"];
if (skills.IsArray())
{
for (rapidjson::SizeType i = 0; i < skills.Size(); i++)
{
Skill tempSkill;
tempSkill.Deserialize(skills[i]);
m_skills.push_back(tempSkill);
}
}
}
}
}
But this seems like a lot of work. You'd have to implement this method in all the classes you want to deserialize themselves. So I was wondering if there's any way to do this automatically, something like the following line of code(JSON.NET):
Movie m = JsonConvert.DeserializeObject<Movie>(json);
so I don't have to write deserialize method for all the classes. Is the way I'm doing it the only way to do it? I'm using rapidjson, but I'm open for trying another library.
I hope the question makes sense :)
Thank you in advance!
To deal with a problem like the you are having a possible solution concentrate all infos in a single function where you make the mapping structure fields <---> entries in the json/xml/ini file. Something like this:
struct abc_t
{
int a ;
string b ;
} ;
void serialize(serializer_t &serializer, abc_t &abc)
{
serializer.exx(abc.a, "abc") ;
serializer.exx(abc.b, "b") ;
}
The problem is how to write this serializer. The solution can be an abstract class like this:
class serializer_t
{
public:
virtual ~serializer_t(void) {}
virtual void exx(int &value, const char *tag) = 0 ;
virtual void exx(string &value, const char *tag) = 0 ;
} ;
then you will have two derived classes, a serializer_writer_t that implements the writing and a serializer_reader_t implementing the reading.
Another possibility is a static polymorphism: this means making the original void serialize(serializer_t &serializer, abc_t &abc) a template function. If you have a composite object then you need to apply this strategy to each sub-object.
Give a look at boost.serialization: you will find a deep discussion about all the trade offs involved in this task
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With