0

I want to parse json file and store it in C++ classes. I need help understanding what is the best way to achieve this?

test.json

{
  "vehicles": [
      {
         "type" : "car" :
           {
             "car1" :
               {
                 "name" : "merc-cla250",
                 "color" : "black",
                },
              "car2" :
               {
                 "name" : "toyota-prius",
                 "color" : "blue",
                },
            }
       },
       {
           "type" : "bike" :
              {
                "bike1" :
                  {
                     "name" : "windsor",
                     "color : "black",
                  },
                "bike2" : 
                  {
                     "name" : "diamond",
                     "color : "black",
                  },
              }
         }
    ]
} 

I want to store these info in classes in C++. In C, I would have defined few structures and stored the info. I am learning C++. Firstly, I just wanted to design header file. I tried following things. Can someone help me improving this? I know, I have written like C style but I appreciate if someone can help me writing better C++ way. Once, I will write the header file, I will start writing cpp file. Thanks in advance! Appreciate your time and help!

vehicle_json.h

#ifndef __VEHICLE_H__
#define __VEHICLE_H__

#include <iostream>
#include <cstdlib>

class vehicle
{
public:
    const std::string& getType(void);
private:
   std::string type;
   carList& carsInfo;       // Can I do this?
   bikeList& bikesInfo;
};

class car
{
public:
    const std::string& getName(void);
    const std::string& getType(void);
private:
   std::string name;
   std::string color;
};
typedef std::vector<car> carList;        

class bike
{
public:
    const std::string& getName(void);
    const std::string& getType(void);
private:
   std::string name;
   std::string color;
};
typedef std::vector<bike> bikeList;

#endif // __VEHICLE_H__
Non-maskable Interrupt
  • 3,841
  • 1
  • 19
  • 26
MeRock027
  • 75
  • 1
  • 8
  • 1
    The best way is to use a 3rd party JSON library for reading the data, and using a "factory" for creating the types – ZivS Jan 07 '18 at 11:56
  • 1
    There are many pre-existing JSON libraries out there. Why not use one of them? – Jesper Juhl Jan 07 '18 at 11:57
  • 1
    I am learning C++. That's why I would like to do it without using 3rd party library. – MeRock027 Jan 07 '18 at 11:59
  • *"what is the best way to achieve this"* - Too broad. – Christian Hackl Jan 07 '18 at 12:09
  • _I want to store these info in classes_ that’s not what you are doing. You would use generic JsonObject and JsonArray classes. You try to load an external representation of your object hierarchy. There is nothing wrong with it if that’s the thing you want do. –  Jan 07 '18 at 12:10
  • @manni66 : what I want is to parse json file and store the info. I need to provide bunch of APIs so that these info can be accessed from outside like getVehicleType(), getCarName() etc.. – MeRock027 Jan 07 '18 at 12:24
  • even you want to parse json yourself, you shouldn't mix parser and data model. – Non-maskable Interrupt Jan 07 '18 at 12:29

1 Answers1

0

Well, there are a bunch of things wrong on a rather formal level:

  • Identifiers with e.g. two consecutive underscores are reserved and you shouldn't use them, not even as include guards.
  • using namespace std; will force all of std onto anyone including that header file, don't do that either. You then continue using std:: everywhere, which is contradicting. However, drop the using .. but keep the std::!
  • A function with no parameters doesn't need an explicit void in C++. In C, it is required to make that clear.
  • Is a car not a vehicle? I think it should be a baseclass.
  • Yes, you can use references as member variables, you must initialize them in the constructor though. I have only had a handful of good usecases for reference members, I don't think this is one of them.
  • some_car.getCarName() -- why repeat the class in the function name? I'd use some_car.getName() instead. Actually, make that some_vehicle.getName(), which fits the baseclass suggested above.
  • You write that you first want to write the header file and then the implementation. Don't do that. Rather, write the code it its entirety first and then extract a header for consumption by other code. The reason is that these are two separate tasks that can be done independently. If you mix them, you get one bigger task with much greater complexity, possibly too much for a beginner.

Now, concerning your JSON question: There is nothing here that requires JSON! Even more, it is preferable if your classes don't depend on any particular JSON representation. Instead, consider a simple function: parse_vehicle_json(std::istream& in). Inside that function, read and parse the input as JSON and then extract a list of vehicles from it. Note that C++ containers are not polymorphic, so you you can't store a car in a vector<vehicle>, you will have to use dynamic allocation with (preferably "smart") pointers instead.

Ulrich Eckhardt
  • 16,572
  • 3
  • 28
  • 55