c++ - 为什么我不能将新元素推回到列表中

标签 c++ pointers reference

当我尝试将新元素推回列表时遇到问题。

本题是根据PushBack()在主体中的调用编写函数实现。所以我的问题只是关于函数 PushBack()

#include <iostream>

 class Node{
 public:
    static Node* MakeNode() { return new Node(100); }
    Node* prev;
    Node* next;
    int value;
 private:
    Node(int num) : value(num), prev(NULL), next(NULL) {}
};

void PushBack(Node* simple, Node* newNode){
    if (simple == NULL){
        //still a empty list
        simple = newNode;
       }
    else{
    //need to loop to the end of list because there is no "tail" in the class
    Node* itr = simple;
    while (itr->next != NULL){
        itr = itr->next;
    }
    newNode->prev = itr;
    itr->next = newNode;
}
return;
}

int main()
{
    Node* simple = NULL;
    PushBack(simple, Node::MakeNode());
    std::cout << (simple == NULL);
    PushBack(simple, Node::MakeNode());
    PushBack(simple, Node::MakeNode());
    PushBack(simple, Node::MakeNode());
    while (simple != NULL){
       std::cout << simple->value << std::endl;
       simple = simple->next;
    }
    return 0;
}

我有两个关于函数 PushBack() 的参数类型的问题:

  1. MakeNode()的返回类型是static Node*,但是为什么我们需要在PushBack()<中设置第二个参数类型作为节点*?为什么不是 static Node *

  2. 一开始,我尝试了 void PushBack(Node* simple, Node* newNode) 但是当程序完成并退出 PushBack() 时,simple再次变为NULL。 所以不能将新元素添加到列表中。我必须使用 void PushBack(Node*& simple, Node* newNode)

为什么我需要在这里添加一个&符号?我想如果我将指针值传递给函数,指针简单可以直接改变。但似乎并非如此。

我的问题和这个段有什么区别:?

void changeVal(int* data){
    for (int i = 0; i < 9; i++)
        *(data + i) = 99;
  }
void main()
{
     int *data;
     data = new int[10];
     changeVal(data);
     for (int i = 0; i < 9; i++)
         std::cout << data[i] << std::endl;
 }

我把指针data传给了changeVal(),函数内部可以改变内容。我不太明白两者之间的区别。

我没能在网上找到一些有用的解释,所以我在这里问。

最佳答案

  1. 不是,MakeNode()的返回类型是Node* .您可以将类方法声明为 static这样您就可以在不需要事先类实例的情况下调用该方法,您可以在类类型本身上调用该方法。 static在这种情况下不是返回值的一部分,它是类方法本身的一部分。至于PushBack() , 没有 static 这样的东西函数参数。该函数作用于 Node 的特定实例类,所以它只是一个普通的指针。

  2. 当您声明 simple参数为 Node* , 你正在传递你的 Node*变量按值。该参数接收 Node*当前值 的本地拷贝多变的。该函数为读取或更改参数值所做的任何操作都是使用该拷贝 完成的,而不是原始 变量。这就是为什么你的 simple main() 中的变量PushBack() 时没有变化退出。

    另一方面,当您声明 simple参数为 Node*& , 你正在传递你的 Node*变量通过引用。参数接收原始Node*内存地址多变的。函数为读取或更改参数值所做的任何操作都是直接使用原始 变量完成的,而不是拷贝。这就是为什么你的 simple main() 中的变量当 PushBack() 发生变化时退出。

引用 本质上是编译器管理的指针。不允许将其设置为 NULL,并且每当您从中读取/向其中写入值时,它都会自动解除引用。因此,如果您将引用视为隐式指针,PushBack(Node*&)功能等同于 PushBack(Node**) (带有额外的编译器验证),类似于以下内容:

void PushBack(Node** simple, Node* newNode){
    if (*simple == NULL){
        //still a empty list
        *simple = newNode;
    }
    else{
        //need to loop to the end of list because there is no "tail" in the class
        Node* itr = *simple;
        while (itr->next != NULL){
            itr = itr->next;
        }
        newNode->prev = itr;
        itr->next = newNode;
    }
    return;
}
PushBack(&simple, ...);

关于c++ - 为什么我不能将新元素推回到列表中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30114553/

相关文章:

c++ - 如何在excel vba中读取c++结构二进制文件

c++ - 如何修复 “Undefined symbols for architecture x86_64:” C++编译器错误?

c++ - 类 undefined reference

c++ - 如何用 C++ 中的引用替换指针?

c++ - 错误 C2504 - 基类未定义

c++ - 我可以在现代 Intel Core CPU 上测量分支预测失败吗?

c - mmap 的指针算法

c - C中的char string [LENGTH]和char * string [LEN]有什么区别

c++ - 结构体上的指针运算

java - Java 8 Streams Filter 和 Collect 是否返回对列表中相同对象的引用?