无法通过指针访问对象的成员

Cannot access member of an object via pointer

本文关键字:对象 成员 访问 指针      更新时间:2023-10-16

这个问题似乎微不足道,但我无法解决它。

我正在尝试通过将根元素传递给函数insert来添加节点。该函数首先检查当前根是否为空,如果是,则只需创建一个新节点并将其设置为根。我的第一次尝试是这样的

#include <iostream>
using namespace std;
class Node {
public:
int data;
Node(int x) {
data = x;
}
};
void insert(Node *node, int x) {
cout << &node << "n";
if(node == NULL) {
node = new Node(x);
}
}

int main () {
Node *aNode;
aNode = NULL;
insert(aNode, 8);
cout << aNode << "n";
return 0;
}

这当然不起作用,因为我按值传递指针,这导致aNode仍然NULL并且通过一些谷歌搜索,我开始知道我需要通过引用传递指针,我的第二次尝试是这样的

#include <iostream>
using namespace std;
class Node {
public:
int data;
Node(int x) {
data = x;
}
};
void insert(Node **node, int x) {
if(*node == NULL) {
*node = new Node(x);
cout << *node->data << "n"; //gives error but program runs fine without it
}
}

int main () {
Node *aNode;
aNode = NULL;
insert(&aNode, 8);
cout << aNode->data << "n";
return 0;
}

现在,由于main打印8中的cout,因此无需插入函数中的cout即可工作,这就是我想要的,但是编译器在插入cout时给出了错误request for member 'data' in '* node', which is of pointer type 'Node*' (maybe you meant to use '->' ?)。我按如下方式更改了插入以运行一些测试,结果令人困惑

void insert(Node **node, int x) {
if(*node == NULL) {
Node *bNode = new Node(x);
cout << bNode << "n"; // prints address of bNode
cout << *node << "n"; // prints NULL which is correct
*node = bNode;
cout << *node << "n"; // prints the same address as of bNode
cout << bNode->data << "n"; // prints 8
cout << *node->data << "n"; // gives error WTF!!!
}
}

有人可以解释一下吗?

@RemyLebeau评论是正确的,并指出了确切的问题。所以这是解决方案。

问题背景

所以我有一个指向 NodeaNode类型的对象的指针,并且有一个函数insert(Node *node, int x).我希望函数插入检查给定的指向节点的指针是否不指向任何内容,然后创建一个新节点并在提供的节点中设置引用。期望在设置引用后aNode也将指向新创建的节点。然而,这是一个错误的期望,因为我是通过值而不是引用传递指针的,这意味着函数中的nodeinsertaNode不同

越野车解决方案

所以解决方案是将aNode的引用传递给函数insert。所以我将我的函数调用更改为insert,到这个

insert(&aNode, 8);

并将insert的函数定义更改为此

void insert(Node **node, int x)

这解决了这个问题,因为**node现在被取消引用到aNode的地址,我能够通过简单地取消引用node来获得它的值*node.当我尝试通过*node->data访问Node的成员时出现问题。原因是*->实际上是运算符,->的优先级高于*。因此,在评估*node->data时,它实际上是以这种方式执行的*(node->data)这意味着编译器实际上试图取消引用node->data而不是node。快速的解决方案只是访问这样的数据(*node(->data。

正确的解决方案

虽然通过括号我能够实现所需的行为,但语法很丑陋。@pm100指出的正确解决方案是在函数定义中使用引用,而不是取消引用两次,这意味着像这样声明函数

void insert(Node *&node, int x)

而不是像这样

void insert(Node **node, int x)

这使得能够像node->data而不是(*node)->data一样访问节点成员

如果您像我一样不熟悉指针,请观看 https://www.youtube.com/watch?v=Rxvv9krECNw