cpp
cpp

Reputation: 3801

push_front() as a linked list member function

How to implement push_front() method for a singly linked list as its member function? The code below does not compile (error: lvalue required as left operand of assignment), because you cannot assign to this pointer. What is a way round this?

#include<algorithm>
using namespace std;

class ListElem{
public:
    ListElem(int val): _val(val){}
    ListElem *next() const { return _next; }
    void next(ListElem *elem) { _next = elem; }
    void val(int val){ _val = val; }
    int val() const { return _val;}
    void print();
    void push_front(int);
private:
    ListElem *_next;    
    int _val;   
};

void ListElem::push_front(int val)
{
    ListElem *new_elem = new ListElem(val); //new node
    new_elem->next( this ); // new node points to old head
    this = new_elem; // make new node the new head, error!
    return;
}

void ListElem::print()
{
    ListElem *pelem = this;
    while(ListElem *pnext_elem = pelem->next())
    {   
        cout << pelem->val() << ' ';
        pelem = pnext_elem;    
    }   
    cout << pelem->val() << endl;
}

int main()
{
    //initialization
    ListElem *head = new ListElem(1);
    ListElem *elem = head;
    for (int ix = 2; ix < 10; ++ix)
    {   
        ListElem *elem_new = new ListElem(ix);
        elem -> next(elem_new);
        elem = elem_new;    
    }   
    head->print();  

    //insert at the beginning
    head->push_front(7);
    head->print();
}

Upvotes: 0

Views: 2280

Answers (3)

molbdnilo
molbdnilo

Reputation: 66441

If you really want to do it that way, you can do it like this:

void ListElem::push_front(int val)
{
    ListElem *new_elem = new ListElem(_val);
    _val = val;
    new_elem->next(_next);
    _next = new_elem;
}

This will replace the data in the "current" node with the new data, and move the "current" data to the new node, which will yield the same list content.
But it's not really correct to conflate a list with its nodes.

The book you linked takes a very non-OO approach to the whole thing (both the Java and the C++ examples look like transliterated C), and conflating the type of a list with the type of its nodes is pretty certain to lead to bugs later.

For instance, if you do this

ListElem* x = head;
head->push_front(99);

then the contents of *x will have changed, which isn't really what you would expect.

Upvotes: 1

sr01853
sr01853

Reputation: 6121

Logically, push_front() must be a method of List class and not of a ListElement class

Upvotes: 2

Paul Evans
Paul Evans

Reputation: 27577

You're using this incorrectly. You want to have a static member called, say, ListElem *head and use that where you were using this. You'll also have to initialise it.

Upvotes: 1

Related Questions