-2

I am studying C++ from Herbert Schildt's book "Teach Yourself C++ 3rd Edition". In one example code, something made me so confused.

#include <iostream>
using namesapce std;

template <class data_t> class list {
    data_t data;
    list *next;

    public:
        list(data_t d);
        void add(list *node) {node->next = this; next = 0; }
        list *getnext() { return next;}
        data_t getdata() { return data;}
};

I didn't write all code in example, I only writed class declaration. In here, I didn't understand one part. First, the "*node" pointer which belongs to "add" function, is using as "node->next" for "*next" pointer. I didn't understand the aim in here, why we don't directly use like {"next=this; next=0;} ? Also, how can we use an empty pointer (*node) to point another empty pointer (*next) ? I am missing maybe some key concepts, thanks for helps.

Shravan40
  • 8,922
  • 6
  • 28
  • 48
semiramis
  • 19
  • 8
  • 3
    Here is a nice list of [C++ books](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). I would skip a book that preaches that struct wiring so popular with universities. Use STL containers instead. –  Dec 26 '16 at 19:59
  • You've got a pointer to a `list`, which contains a pointer to another `list`, which contains a pointer to another `list`... this is the normal way of linked-lists. But you'll be much happier using `std::list` from the standard library than using this! – Jack Deeth Dec 26 '16 at 20:16

1 Answers1

0

In the function add():

template<typename data_t>
class list {
    // ...
    void add(list *node) {node->next = this; next = 0; }
    // ...
};

The point of the function is to add this to the list, as the next element after node. Think about it like a train: add() tells the current car to hook itself onto the back of another car, with the function's parameter telling it which car to link to.
Note that this function expects node to not be a null pointer; if it is null, you'll probably get a segmentation fault.

void add(list* node) {
    node->next = this; // Tells "node" to register the current node as its "next" node.
                       // Should first check whether "node" is a valid pointer.
    next = 0;          // Tells the current node to register a null pointer as its "next" node,
                       //  signifying that it's currently the last node in the list.
                       // Note that instead of assigning 0, it should instead assign either
                       //  "nullptr" (C++11 or later) or "NULL" (pre-C++11).
}

Therefore, when used like this:

list<int> start(42), second(24);
second.add(&start);

It will do the following:

(&start)->next = &second;
(&second)->next = 0;

This creates a singly linked list, which looks like this:

Start: "start"
  --> Next: "second"
    --> Next: None.

Or, more concisely:

start->second->NULL

Remember, when inside a non-static member function, any member variable accesses are assumed to operate on this unless otherwise specified.

template<typename data_t>
void list<data_t>::add(list* node) {
    node->next = this; // Operates on node, not on this.
    next = 0;          // Operates on this; becomes "this->next = 0;"
}

If this function intstead was just {next = this; next = 0;}, then it would be:

template<typename data_t>
void list<data_t>::add(list *node) {
    this->next = this; // Bad.  Creates a circular linked list, where "this" is ALWAYS the
                       //  next node after "this".
    this->next = 0;    // Renders the above line entirely pointless, by indicating that there
                       //  are no nodes after "this".
}