jeudi 29 septembre 2016

How to declare friend classes while using decorator and iterator design patterns

I have created a ListAsDLL class (doubly linked list) by decorating a ListAsSLL class (singly linked list). Now I would like to incorporate an Iterator class to cycle through the ListAsDLL class. My code is as follows:

#include <iostream>
using namespace std;

class ListAsSLL
{
protected:
    struct node{
        int i;
        struct node* next;
    };
    node* head;
    node* tail;
    int listSize;

public:
    ListAsSLL()
    {
        head = 0;
        tail = 0;
        listSize = 0;
    }
    virtual void addToBeginning(int i)
    {
        node * temp = new node;
        temp->i = i;
        if(head==0){
            temp->next = 0;
            tail = temp;
        }else if(head == tail) {
            temp->next = tail;
        }
        else{
            temp->next = head;
        }
        head = temp;
        listSize++;
    }
    virtual void print()
    {
        node* temp = head;
        for (int i = 0; i < listSize; ++i) {
            cout<<temp->i<<" "<<endl;
            temp = temp->next;
        }
    }
};

class Decorator : public ListAsSLL
{
private:
    ListAsSLL* list;
public:
    Decorator(ListAsSLL* l)
    {
        list = l;
    }
    virtual void addToBeginning(int i)
    {
        list->addToBeginning(i);
    }
    virtual void print()
    {
        list->print();
    }
};

class PreviousDecorator : public Decorator
{
protected:
    struct dnode : public node
    {
        node* prev;
    };
    dnode* head;
    dnode* tail;
    int listSize;

public:
    PreviousDecorator(ListAsSLL* l) : Decorator(l)
    {
        listSize = 0;
        head = 0;
        tail = 0;
    }
    virtual void addToBeginning(int i)
    {
        Decorator::addToBeginning(i);
        dnode * temp = new dnode;
        temp->i = i;
        if(head==0){
            temp->next = 0;
            tail = temp;
        }else if(head == tail) {
            temp->next = tail;
            tail->prev = temp;
        }
        else{
            temp->next = head;
            tail->prev = temp;
        }
        temp->prev = 0;
        head = temp;
        listSize++;
    }
    virtual void print()
    {
        Decorator::print();
        node* temp = head;
        for (int i = 0; i < listSize; ++i) {
            cout<<temp->i<<" "<<endl;
            temp = temp->next;
        }
    }
    friend class DLLIterator;
};

class ListAsDLL : public ListAsSLL
{
public:
    virtual void addToBeginning(int i){}
    virtual void print(){}
};

class DLLIterator
{
private:
    ListAsDLL* dll;
public:
    DLLIterator(ListAsDLL* dll)
    {
        this->dll = dll;
    }
    int getFirst()
    {
        return dll->head->i;
    }
};

int main() {
    ListAsSLL* dll = new PreviousDecorator(new ListAsDLL());
    dll->addToBeginning(20);
    DLLIterator* it = new DLLIterator((ListAsDLL*) dll);
    cout<<it->getFirst()<<endl;

    delete dll;
    delete it;
    return 0;
}

The only problem is that because I am passing in a ListAsDLL as a parameter to the Iterator class I am unable to access the protected attributes of the class it is being decorated with. Therefore I cannot access dll->head->i.

Firstly, am I using the decorator design pattern correctly? And secondly how can I access the protected attributes of a class that a friend class has been decorated with.

Aucun commentaire:

Enregistrer un commentaire