Search code examples
c++pointersreferencepass-by-reference

Why with dot operator value is not changed in c++?


I am from Javascript background and was experimenting with c++ where i wanted to mutate a struct member in an array in the caller function as below.

#include<iostream>
#include<vector>

using namespace std;

typedef struct Node{
    int value;
    Node(int val){
        this->value = val;
    }
};
void changeValueByDot(Node* p, int idx){
    Node n = *(p + idx);
    n.value = 54;

}
void changeValueByArrow(Node* p, int idx){
    Node* n = (p + idx);
    n->value = 32;
};

int main(){
    vector<Node> v = {
        Node(1),
        Node(2)
    };
    
    
    changeValueByDot(v.data(), 1);
    cout<<"After changing by dot:"<<v[1].value<<endl;
    changeValueByArrow(v.data(), 1);
    cout<<"After changing by arrow:"<<v[1].value<<endl;
    
    return 0;
}

Now my confusion is why dot operator is unable to do permanent change while arrow operator could. My expectation with dot was to first reach the place obtain node and change its value. I am not sure if the node at that location is getting copied and changes are done in copied node.

I tried with both vector and fixed size array only to get same result.

Please help me in understanding this. Thanks in advance!


Solution

  • On this line:

    Node n = *(p + idx);
    

    the variable n is a copy of the node on the right hand side. Modifying n.value won't change the node referred to on the right hand side.

    If you want n to refer to the dereferenced node, then use a reference:

    Node & n = *(p + idx);
      // ^ 
    

    Now changes to n will be reflected in changes to *(p + idx)


    Note that this is not a problem when you do:

    Node* n = (p + idx);
    

    because while n is still a copy, it's a copy of a pointer, and modifying n->value will actually change the value member of the same object pointed at by p + idx.