Why can't I drop the new item into the list

I am facing a problem when I am trying to drop a new item into a list.

This problem is how to write the implementation of the PushBack () function according to its call in the main body. So my question is about function 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;
}

      

I have two questions about the type of the function argument PushBack()

:

  • the return type MakeNode()

    is static Node*

    , but why do we need to set the second argument type to PushBack()

    how Node*

    ? why not static Node *

    ?

  • At the beginning I tried void PushBack(Node* simple, Node* newNode)

    , but when the program finished and exited PushBack()

    , simple

    it will again NULL

    . Therefore, new items cannot be added to the list. I have to use void PushBack(Node*& simple, Node* newNode)

    .

Why do I need to add a symbol &

here? I think that if I pass the value of the pointer to the function, the simple pointer can be changed directly. But it doesn't seem to be the case.

What is the difference between my problem and this segment :?

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;
 }

      

I passed a pointer data

to changeVal()

, and the content can be changed inside the function. I don't quite understand the difference between the two.

I haven't been able to find a helpful explanation online, so I'm asking here.

0


source to share


2 answers


  • No, the return type MakeNode()

    is Node*

    . You can declare a class method like static

    so that you can call the method without having to use an instance of the class beforehand, you call the method on the class type itself. static

    in this case, it is not part of the return value, it is part of the class method itself. As for PushBack()

    , there is no such function as a function parameter static

    . The function acts on a specific instance of the class Node

    , so it is a normal pointer.

  • When you declare a parameter simple

    as Node*

    , you are passing the variable Node*

    by value . The parameter gets a local copy of the current value of the variable Node*

    . Anything the function does to read or change a parameter value is done using that copy, not the original variable. This is why your variable simple

    in has main()

    n't changed on exit PushBack()

    .

    On the other hand, when you declare a parameter simple

    as Node*&

    , you are passing the variable Node*

    by reference . The parameter gets the memory address of the original variable Node*

    . Anything a function does to read or change a parameter value is done using the original variable directly, not a copy. This is why your variable simple

    in main()

    changed on exit PushBack()

    .

A link is essentially a compiler-managed pointer. It can never be set to NULL, and it is automatically played whenever you read / write a value from / to it. So, if you think of a reference as an implicit pointer, PushBack(Node*&)

this is functionality equivalent PushBack(Node**)

(with additional compiler checking), similar to the following:

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, ...);

      

+2


source


You need to pass in a pointer reference, not just a pointer, so that the address given by a simple one can be changed inside the PushBack function.

Here is the definition from MSDN .

Pointer references can be declared in the same way as object references. Declaring a pointer reference yields a mutable value that is used like a normal pointer.

Let me create a simple illustration:

Address | Value

[0001]->
[0002]->
[0003]->
[0004]->
......
[nnnn]->

      

When you run your program, you have a variable simply pointing to NULL:



[0001]->NULL 
[0002]
[0003]
[0004]
......
[nnnn]

      

When you call PushBack from the beginning, you simply pass the value specified by a simple variable that is NULL.

[0001]->NULL 

      

When you change your value inside your PushBack function, you are just changing a local copy of that function, not a simple pointer variable. After your call to PushBack is complete, your simple variable still points to NULL.

Now, when you pass a reference pointer, you are passing the mutable value to a simple variable used as a pointer. When you change the value of the pointer, you also change the value indicated by the actual simple variable. After calling PushBack using a pointer reference, the simple variable will now point to the address of the new instance returned by the MakeNode.

[0001]->newNode 
[0002]
[0003]
[0004]
......
[nnnn]

      

+1


source







All Articles