Here is my constructor.

SceneContainer::SceneContainer()
   :
    m_BVH(Allshapes, 0)
    {
        ParseJSONDataIntoShapeData("ShapeList.json");
    }

Here is the scene class declaration.

class SceneContainer{
public:
void ParseJSONDataIntoShapeData(std::string filename);

private:
BVHNode m_BVH;
std::vector<shape*> Allshapes;
};

So given a JSON file like this.

  {
      "scene": {
        "shape": [{
          "center": "1.0 1.0 1.0",
          "radius": 1,
          "_name": "sphere1",
          "_type": "sphere"
        },
{
          "center": "2.0 2.0 2.0",
          "radius": 1,
          "_name": "sphere2",
          "_type": "sphere"
        },
{
          "center": "3.0 3.0 3.0",
          "radius": 1,
          "_name": "sphere3",
          "_type": "sphere"
        },
{
          "center": "3.0 3.0 3.0",
          "radius": 1,
          "_name": "sphere4",
          "_type": "sphere"
        }]
      }
    

parseJSONDataIntoShapeData would then iterate over all shapes in the file and push_back a pointer to the shape that was created in the file. Some Pseudo code for this would look like.

for(all shapes in json file)
    Create shape pointer from shape data
    push_back shape pointer to AllShapes.

after parseJSONdata is called there would be four shapes in the Allshapes vector. However, due to how the constructor works with my original implementation, m_BVH gets initialized with an empty vector because ParseJSONData gets called after m_BVH is initialized whereas I want it to get initialized with the shape data in it.

1

There are 1 best solutions below

0
On

So, you have some function which assigns to a member of the class. But you also have another member of the class which is going to consume the contents of the first member.

What you ought to have is a function that returns the data which is used to initialize the first member, and then you can use it as part of the constructor for the second:

class SceneContainer{
public:
  //Doesn't set data into the object.
  static std::vector<shape*> ParseJSONDataIntoShapeData(std::string filename);

  //Setting the data into the object is a separate step.
  void ResetJSONDataIntoShapeData(std::string filename)
  {
    //Free Allshapes;
    Allshapes = ParseJSONDataIntoShapeData(filename);
    m_BVH.reassign(Allshapes, 0); //Tells the m_BVH object that its data has changed.
  }

private:
  std::vector<shape*> Allshapes;
  BVHNode m_BVH;
};

SceneContainer::SceneContainer()
  : Allshapes(ParseJSONDataIntoShapeData("ShapeList.json"))
  , m_BVH(Allshapes, 0)
  {}

Note that the order of the declaration of Allshapes and m_BVH has changed. This is important, because it is the order that these objects are declared in which will determine the order of their initialization.