C++中指向结构体的指针

4
为了完成我的作业,我需要在C++中实现一个列表,因此我定义了一个结构体:
struct Node {
    int value;
    Node * next;
    Node * operator [] (int index)//to get the indexed node like in an array
    {
        Node *current = this;
        for (int i = 0; i<index; i++)
        {
            if (current==NULL) return NULL;
            current = current->next;
        }
        return current;
    }
};

当我在实际的结构中使用它时,它运行得很好:
Node v1, v2, v3;
v1.next = &v2;
v2.next = &v3;
v3.value = 4;
v3.next = NULL;
cout<<v1[2]->value<<endl;//4
cout<<v2[1]->value<<endl;//4
cout<<v3[0]->value<<endl;//4; works just as planned
cout<<v3[1]->value<<endl;//Segmentation fault

但当我尝试使用指针时,事情变得混乱了:

Node *v4, *v5, *v6;
v4 = new Node;
v5 = new Node;
v6 = new Node;
v4->next = v5;
v4->value = 44;
v5->next = v6;
v5->value = 45;
v6->next = NULL;
v6->value = 4646;
//cout cout<<v4[0]->value<<endl; compiler says it's not a pointer
cout<<v4[0].value<<endl;//44
cout<<v4[1].value<<endl;//1851014134
cout<<v4[2].value<<endl;//45
cout<<v4[3].value<<endl;//1851014134
cout<<v4[4].value<<endl;//4646
cout<<v4[5].value<<endl;//1985297391;no segmentation fault
cout<<v6[1].value<<endl;//1985297391;no segmentation fault even though the next was NULL
delete v4;
delete v5;
delete v6;

虽然函数可以工作,但我有一些问题:

  1. 为什么指针示例中返回的值是一个结构而不是指针?
  2. 为什么元素现在具有加倍的索引,它们之间的元素是什么?
  3. 为什么没有分段错误?

如果有人能解释这些问题或给我学习的来源,我将非常感激。


在第二段代码片段中,您明显存在未定义行为,因为您使用了v1v2成员的value而没有初始化它。我建议添加一个默认构造函数来将该值设置为0 - Guillaume Racicot
2个回答

5
那是因为v4 [0](以及其他元素)实际上并没有调用您的Node :: operator []。 这是因为v4不是Node,而是Node *,并且指针在operator []后有一个内置含义:v4 [i]== *(v4 + i)(也就是说,我们只是索引到该“数组”中)。因此,当您编写类似v4 [3]这样的内容时,这并不是在调用operator [](3)...而是在从v4之后的三个Node内存位置返回给您一个Node,基本上只是垃圾。

要实现您想要的操作,您必须先取消引用指针:

(*v4)[0]
(*v6)[1]
// etc

谢谢您的回答!它解释了一切,因为我不知道有内置运算符。这是否意味着我无法更改运算符,使其按照我最初想要的方式工作? - dkuznietsov
@undocreado,你应该不要使用运算符。为链表提供operator[]没有意义。 - Barry
我想要它,因为这样会使像elementAt、deleteAt或insert这样的方法更容易编写,因为我只需获取列表第一个节点的索引成员即可。是制作一些函数还是在每个方法中编写代码更好呢? - dkuznietsov
@undocreado ... 这是一种在链表中不支持的操作,没有意义。 - Barry
那就是我得到的任务,所以无论如何我都需要实现它。在这种情况下,你会推荐什么? - dkuznietsov

1
通过这样做

v4 = new Node;
cout<<v4[0].value<<endl;//44
cout<<v4[1].value<<endl;//1851014134
cout<<v4[2].value<<endl;//45
cout<<v4[3].value<<endl;//1851014134
cout<<v4[4].value<<endl;//4646
cout<<v4[5].value<<endl;//1985297391;no segmentation fault

你没有调用结构体Node的operator[],而是进行了指针解除引用,v4[1]相当于++v4; *v4;。因此,这段代码会导致不可预测的行为,因为你在解除引用一些垃圾值。为了让它按照你的意愿工作,你需要将它修改为:
cout<<v4->operator[](0).value<<endl;
cout<<v4->operator[](1).value<<endl;
cout<<v4->operator[](2).value<<endl;
...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接