为什么点运算符的值在 C++ 中没有改变?

1 c++ pointers reference pass-by-reference

我来自 Javascript 背景,正在试验 C++,我想在调用函数中改变数组中的结构成员,如下所示。

#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;
}
Run Code Online (Sandbox Code Playgroud)

现在我的困惑是为什么点运算符无法进行永久性更改而箭头运算符可以。我对 dot 的期望是首先到达获取节点的位置并更改其值。我不确定该位置的节点是否正在被复制,并且更改是否在复制的节点中完成。

我尝试使用向量和固定大小的数组只是为了得到相同的结果。

请帮助我理解这一点。提前致谢!

cig*_*ien 8

在这一行:

Node n = *(p + idx);
Run Code Online (Sandbox Code Playgroud)

该变量n是右侧节点的副本。修改n.value不会更改右侧引用的节点。

如果要n引用取消引用的节点,请使用引用:

Node & n = *(p + idx);
  // ^ 
Run Code Online (Sandbox Code Playgroud)

现在更改n将反映在更改*(p + idx)


请注意,当您执行以下操作时,这不是问题:

Node* n = (p + idx);
Run Code Online (Sandbox Code Playgroud)

因为 whilen仍然是一个副本,它是一个指针的副本,修改n->value实际上会改变value指向的同一对象的成员p + idx