Why does the member variable change after invoking the assignment operator in rapidjson?

StackOverflow https://stackoverflow.com/questions/23070593

  •  03-07-2023
  •  | 
  •  

Question

The source codes shown below is a part of checking members of an object of the Document class. We tried to create an object of the Value Class that is ‘memberObject’ and to store the object reference into ‘_value’ Value reference private member variable. Looking at the outputs, we can see type of the object is 3 (Object). However, after assigning _value reference variable with memberObject, the output shows the type changed to 0 (NULL). We expect that type change like this should not happen. Could you explain why this happens?

  for (Value::MemberIterator itr = _document.MemberBegin(); itr != _document.MemberEnd(); itr++)
  {
        _itr = itr;

        _name = itr->name.GetString();
        _objectTypeID = (int)itr->value.GetType();

        cout << "Member [" << _name << "] - type is [" << _objectTypeID << "]" << endl;

        _typeID = _objectTypeID;

        if (itr->value.IsObject())
        {
              Value& memberObject = _document[_name.c_str()];
              cout << "Value type(1): " << memberObject.GetType() << endl;

              _value = (Value&)memberObject;
              cout << "Value type(2): " << memberObject.GetType() << endl;
        }


        _st.push(_itr);

        parseValue();

        _itr = _st.top();  // returns the next element in the stack
        _st.pop();         // removes an element from the stack
  }

"firmwareSettings": {
    "manageFirmware": false,
    "firmwareBaselineUri": ""
},

Member [firmwareSettings] - type is [3]
Value type(1): 3
Value type(2): 0

Was it helpful?

Solution

This behavior is expected as the assignment operator for GenericValue uses move semantics.

Here is the assignment operator for GenericValue in rapidjson:

 //! Assignment with move semantics.
    /*! \param rhs Source of the assignment. It will become a null value after assignment.
    */
    GenericValue& operator=(GenericValue& rhs) {
        RAPIDJSON_ASSERT(this != &rhs);
        this->~GenericValue();
        memcpy(this, &rhs, sizeof(GenericValue));
        rhs.flags_ = kNullFlag;
        return *this;
    }

When memberObject is assigned to _value, the assignment operator kicks in changing the flags_ member which is the value returned by the GetType() method of the rvalue object.

For more details on move semantics, please see What are move semantics?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top