2

I wanted to make a simple linked list class and other data structures in C++ to get used to object oriented programming. After editing my old C code I had something like this (I have just included one of the functions):

template<typename T> class llist
{
    public:
        T data;
        llist<T>* next;

        llist() {next=nullptr;}
        llist(const T& d) {data=d;next=nullptr;}
};

template<class T> llist<T>** llistAdd(llist<T> **l,const T& d)
{
    llist<T> *temp=*l;
    (*l)=new llist<T>(d);
    (**l).next=temp;
    return &(**l).next;
}

Which is used like:

int main()
{
    llist<int>* my_integer_list = nullptr;

    llistAdd(&my_integer_list,42);
    llistAdd(&my_integer_list,128);
    llistAdd(&my_integer_list,1337);

    for(auto itr = &my_integer_list; (*itr) != nullptr; llistItrAdv(&itr))
        cout<<(**itr).data<<endl;

    llistClear(&my_integer_list);

    return 0;
}

Which all works perfectly. The problem is that the C++ OOP-style uses methods instead of functions like llistAdd(..). The problem is that my code works with pointer-to-pointers and even pointer-to-pointer-to-pointers (see llistItrAdv(..)). If I use methods I will need to do something like:

template<typename T> llist<T>* llist<T>::Add(const T& d)
{
    llist<T> *temp = new llist<T>(d);
    temp->next = this;
    return temp;
}

int main()
{
    llist<int>* my_integer_list = nullptr;

    my_integer_list = my_integer_list->Add(42);

    my_integer_list = my_integer_list->Clear();

    return 0;
}

This however makes ugly code and is prone to memory leaks. There must be a better way to do this with methods but I really can't think of anything. I tried to make methods for pointers, but that is illegal in C++. Could you guys educate me on how proper OOP-style deals classes like mine?

3
  • 1
    Why not use std::list or std::vector and let the stdlib do the hard job? Commented Jun 20, 2013 at 17:56
  • 1
    A combination of getting familiar with OOP and studying data structures. I have to know what's going on under the hood :P Commented Jun 20, 2013 at 18:05
  • @MadPidgeon: A list is not complicated enough to get used to OOP. There's no need to inherit, use virtual functions, and so on. Try something more complicated. Computer game, perhaps. On other hand, you don't seem to know about "rule of three", so you should read about it. Commented Jun 20, 2013 at 19:01

1 Answer 1

3

The problem you've encountered stems from the fact that your llist class is really a single node in a linked list, rather than the whole list, so it doesn't make sense for it to have an add method. You'll notice that this was actually the case in your non-OOP code as well - the llistAdd function acts not on an llist object, but on an object (here just a pointer) that has a reference to an llist object. This suggests the solution to your problem: rename your old class to llistnode and create a new llist class with a pointer to a llistnode that is the head of the list and on this new class implement the

template<typename T> class llistnode
{
  public:
    T data;
    llistnode<T>* next;

    llistnode() {next=nullptr;}
    llistnode(const T& d) {data=d;next=nullptr;}
};

template<typename T> class llist
{
  private:
    llistnode<T>* head;

  public:
    void Add(const T& d) {
        llistnode<T>* new_node = new llistnode<T>(d);
        new_node.next = head;
        head = new_node;
    }
};
Sign up to request clarification or add additional context in comments.

4 Comments

I don't understand your code. Which one is the llistnode and where do you keep the T data;?
Whoops! I used the wrong node type inside of llist - hopefully it makes sense now.
Thank you so much for this answer. I really should have seen this. I have a small question though: Say I want to iterate through the list and insert nodes in the list. How do I do that? In this code I can only add nodes at the beginning. Or at least, am I not missing something?
Remember that for a linked list, in order to insert a new element at a position other than the front (or back, if the list were doubly-linked) you need a reference to the node directly before the position you would like to insert at. So, it makes sense to add an insertAfter method to the node class which does this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.