MadPidgeon
MadPidgeon

Reputation: 245

object oriented programming style and pointers to pointers

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?

Upvotes: 2

Views: 990

Answers (1)

Caleb
Caleb

Reputation: 191

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

Upvotes: 3

Related Questions