Ereditarietà e templati

di il
17 risposte

Ereditarietà e templati

#ifndef NODETYPE_H
#define NODETYPE_H

template <class Type>
struct nodeType
{
    Type info;
    nodeType<Type> *link;
};

#endif // NODETYPE_H
#ifndef LINKEDLIST_H
#define LINKEDLIST_H

#include "nodeType.h"
#include <iostream>

template <class Type>
class linkedList
{
    public:
        linkedList();
        ~linkedList();
        linkedList(const linkedList<Type>& other);
        linkedList& operator=(const linkedList<Type>& other);
        void destroyList();
        void initializeList();
        void print() const;
        virtual bool search(const Type& searchItem) const = 0;
        virtual void insertFirst(const Type& newItem) = 0;
        virtual void insertLast(const Type& newItem) = 0;
        virtual void deleteNode(const Type& nodetodel) = 0;
    protected:
        int count;
        nodeType<Type> *first;
        nodeType<Type> *last;
    private:
        void copyList(const linkedList<Type>& other);
};

#endif // LINKEDLIST_H
#include "linkedList.h"

template <class Type>
linkedList<Type>::linkedList()    //ctor
{
    first = NULL;
    last = NULL;
    count = 0;
}

template <class Type>
linkedList<Type>::~linkedList()   //dtor
{
    destroyList();
}

template <class Type>
linkedList<Type>::linkedList(const linkedList<Type>& other)
{
     first = NULL;
     copyList(other);
}

template <class Type>
linkedList<Type>& linkedList<Type>::operator=(const linkedList<Type>& rhs)
{
    if (this != &rhs)
        copyList(rhs);

    return *this;
}

template <class Type>
void linkedList<Type>::destroyList()
{
    nodeType<Type> *current;

    while(first!=NULL)
    {
        current = first;
        first = first->link;
        delete current;
    }

    last = NULL;
    count = 0;
}

template <class Type>
void linkedList<Type>::initializeList()
{
    destroyList();
}

template <class Type>
void linkedList<Type>::print() const
{
    nodeType<Type> *current;

    current = first;

    while(current != NULL)
    {
        std::cout << current->info;
        current = current->link;
    }
}

template <class Type>
void linkedList<Type>::copyList(const linkedList<Type>& other)
{
    nodeType<Type> *current;
    nodeType<Type> *newNode;

    if(first != NULL)
        destroyList();

    if(other.first == NULL)
        initializeList();
    else
    {
        current = other.first;

        count = other.count;
        first = new nodeType<Type>;
        first->info = current->info;
        first->link = NULL;

        last = first;

        current = current->link;

        while(current != NULL)
        {
            newNode = new nodeType<Type>;
            newNode->info = current->info;
            newNode->link = NULL;

            last->link = newNode;
            last = newNode;

            current = current->link;
        }
    }
}
#ifndef ORDEREDLIST_H
#define ORDEREDLIST_H

#include "linkedList.h"

template <class Type>
class OrderedList : public linkedList<Type>
{
    public:
        bool search(Type& item);
        void insert(Type& item);
        void deleteNode(Type& item);
    protected:
    private:
};

#endif // ORDEREDLIST_H
#include "OrderedList.h"

template<class Type>
bool OrderedList<Type>::search(Type& item)
{
    bool found = false;
    nodeType<Type> *current;
    current = first;

    while(current != NULL && !found)
    {
        if(current->info >= item)
            found = true;
        else
            current = current->link;
    }

    if(found)
        found = (current->info == item);

    return found;
}

template<class Type>
void OrderedList<Type>::insert(Type& item)
{
    nodeType<Type> *current; //pointer to traverse the list
    nodeType<Type> *trailCurrent; //pointer just before current
    nodeType<Type> *newNode;

    bool found;
    newNode = new nodeType<Type>; //create the node
    newNode->info = item; //store newItem in the node
    newNode->link = NULL; //set the link field of the node
    //to NULL
    if (first == NULL) //Case 1
    {
        first = newNode;
        last = newNode;
        count++;
    }
    else
    {
        current = first;
        found = false;
        while (current != NULL && !found) //search the list
            if (current->info >= newItem)
                found = true;
            else
            {
                trailCurrent = current;
                current = current->link;
            }

        if (current == first) //Case 2
        {
            newNode->link = first;
            first = newNode;
            count++;
        }
        else //Case 3
        {
            trailCurrent->link = newNode;
            newNode->link = current;
            if (current == NULL)
                last = newNode;
            count++;
        }
    }
}
La classe OrderedList dovrebbe ereditare la classe linkedList ma quando provo a fare il build il debugger riporta
D:\programmic++\linked_list\OrderedList.cpp|36|error: 'first' was not declared in this scope|
e così via per tutte le variabili membro dichiarate in linkedList. Cosa sbaglio?

17 Risposte

  • Re: Ereditarietà e templati

    A me da errore perché non hai definito le quattro funzioni virtuali in OrderedList (occhio ai prototipi).
  • Re: Ereditarietà e templati

    Devo per forza implementare tutte le funzioni virtuali? Comunque ho aggiunto const anche nelle funzioni della classe OrderedList ma il risultato non cambia
  • Re: Ereditarietà e templati

    roov_raven ha scritto:


    Devo per forza implementare tutte le funzioni virtuali?
    Si, altrimenti il codice non compila a prescindere.

    *edit* corretto errore.
  • Re: Ereditarietà e templati

    #include "OrderedList.h"
    
    template<class Type>
    bool OrderedList<Type>::search(const Type& item)
    {
        bool found = false;
        nodeType<Type> *current;
        current = first;
    
        while(current != NULL && !found)
        {
            if(current->info >= item)
                found = true;
            else
                current = current->link;
        }
    
        if(found)
            found = (current->info == item);
    
        return found;
    }
    
    template<class Type>
    void OrderedList<Type>::insert(const Type& item)
    {
        nodeType<Type> *current; //pointer to traverse the list
        nodeType<Type> *trailCurrent; //pointer just before current
        nodeType<Type> *newNode;
    
        bool found;
        newNode = new nodeType<Type>; //create the node
        newNode->info = item; //store newItem in the node
        newNode->link = NULL; //set the link field of the node
        //to NULL
        if (first == NULL) //Case 1
        {
            first = newNode;
            last = newNode;
            count++;
        }
        else
        {
            current = first;
            found = false;
            while (current != NULL && !found) //search the list
                if (current->info >= newItem)
                    found = true;
                else
                {
                    trailCurrent = current;
                    current = current->link;
                }
    
            if (current == first) //Case 2
            {
                newNode->link = first;
                first = newNode;
                count++;
            }
            else //Case 3
            {
                trailCurrent->link = newNode;
                newNode->link = current;
                if (current == NULL)
                    last = newNode;
                count++;
            }
        }
    }
    
    template<class Type>
    void OrderedList<Type>::insertFirst(const Type& item)
    {
        insert(item);
    }
    
    template<class Type>
    void OrderedList<Type>::insertLast(const Type& item)
    {
        insert(item);
    }
    
    template<class Type>
    void OrderedList<Type>::deleteNode(const Type& item)
    {
        nodeType<Type> *current; //pointer to traverse the list
        nodeType<Type> *trailCurrent; //pointer just before current
        bool found;
    
        if (first == NULL) //Case 1
            std::cout << "Cannot delete from an empty list." << endl;
        else
        {
            current = first;
            found = false;
            while (current != NULL && !found) //search the list
                if (current->info >= deleteItem)
                    found = true;
                else
                {
                    trailCurrent = current;
                    current = current->link;
                }
    
            if (current == NULL) //Case 4
                std::cout << "The item to be deleted is not in the "
                          << "list." << endl;
            else
                if (current->info == deleteItem)
                {
                    if (first == current) //Case 2
                    {
                        first = first->link;
    
                        if (first == NULL)
                            last = NULL;
    
                        delete current;
                    }
                    else //Case 3
                    {
                        trailCurrent->link = current->link;
    
                        if (current == last)
                            last = trailCurrent;
    
                        delete current;
                    }
    
                    count--;
                }
    
                else //Case 4
                    std::cout << "The item to be deleted is not in the "
                              << "list." << endl;
        }
    }//end deleteNode
    
    Ora ho implementato tutte le funzioni virtuali ma continua a darmi lo stesso problema di prima
  • Re: Ereditarietà e templati

    Il prototipo deve coincidere esattamente:
    
    template<class Type>
    bool OrderedList<Type>::search(const Type& item) const
    {
    
    E nella funzione insert, newItem non esiste. Controlla bene.
    Fatte le correzioni a me compila.
  • Re: Ereditarietà e templati

    #include "OrderedList.h"
    
    template<class Type>
    bool OrderedList<Type>::search(const Type& searchItem)
    {
        bool found = false;
        nodeType<Type> *current;
        current = first;
    
        while(current != NULL && !found)
        {
            if(current->info >= searchItem)
                found = true;
            else
                current = current->link;
        }
    
        if(found)
            found = (current->info == searchItem);
    
        return found;
    }
    
    template<class Type>
    void OrderedList<Type>::insert(const Type& item)
    {
        nodeType<Type> *current; //pointer to traverse the list
        nodeType<Type> *trailCurrent; //pointer just before current
        nodeType<Type> *newNode;
    
        bool found;
        newNode = new nodeType<Type>; //create the node
        newNode->info = item; //store newItem in the node
        newNode->link = NULL; //set the link field of the node
        //to NULL
        if (first == NULL) //Case 1
        {
            first = newNode;
            last = newNode;
            count++;
        }
        else
        {
            current = first;
            found = false;
            while (current != NULL && !found) //search the list
                if (current->info >= item)
                    found = true;
                else
                {
                    trailCurrent = current;
                    current = current->link;
                }
    
            if (current == first) //Case 2
            {
                newNode->link = first;
                first = newNode;
                count++;
            }
            else //Case 3
            {
                trailCurrent->link = newNode;
                newNode->link = current;
                if (current == NULL)
                    last = newNode;
                count++;
            }
        }
    }
    
    template<class Type>
    void OrderedList<Type>::insertFirst(const Type& newItem)
    {
        insert(newItem);
    }
    
    template<class Type>
    void OrderedList<Type>::insertLast(const Type& newItem)
    {
        insert(newItem);
    }
    
    template<class Type>
    void OrderedList<Type>::deleteNode(const Type& nodetodel)
    {
        nodeType<Type> *current; //pointer to traverse the list
        nodeType<Type> *trailCurrent; //pointer just before current
        bool found;
    
        if (first == NULL) //Case 1
            std::cout << "Cannot delete from an empty list." << endl;
        else
        {
            current = first;
            found = false;
            while (current != NULL && !found) //search the list
                if (current->info >= nodetodel)
                    found = true;
                else
                {
                    trailCurrent = current;
                    current = current->link;
                }
    
            if (current == NULL) //Case 4
                std::cout << "The item to be deleted is not in the "
                          << "list." << endl;
            else
                if (current->info == nodetodel)
                {
                    if (first == current) //Case 2
                    {
                        first = first->link;
    
                        if (first == NULL)
                            last = NULL;
    
                        delete current;
                    }
                    else //Case 3
                    {
                        trailCurrent->link = current->link;
    
                        if (current == last)
                            last = trailCurrent;
    
                        delete current;
                    }
    
                    count--;
                }
    
                else //Case 4
                    std::cout << "The item to be deleted is not in the "
                              << "list." << endl;
        }
    }//end deleteNode
    
    #ifndef ORDEREDLIST_H
    #define ORDEREDLIST_H
    
    #include "linkedList.h"
    
    template <class Type>
    class OrderedList : public linkedList<Type>
    {
        public:
            bool search(const Type& searchItem);
            void insert(const Type& item);
            void deleteNode(const Type& nodetodel);
            void insertFirst(const Type& newItem);
            void insertLast(const Type& newItem);
        protected:
        private:
    };
    
    #endif // ORDEREDLIST_H
    
    Ho corretto i fingerprints ma ancora nada, sempre lo stesso errore
  • Re: Ereditarietà e templati

    Questa è la funzione in LinkedList:
    
    virtual bool search(const Type& searchItem) const = 0;
    
    Questa è la funzione in Ordered list:
    
    bool search(const Type& searchItem);
    
    Non ti sembra ci sia un "const" in meno?
    Come già detto i due prototipi devono essere identici (virtual a parte), altrimenti per il compilatore sono due funzioni diverse.
  • Re: Ereditarietà e templati

    Ho corretto anche questo ma nulla, è sempre un problema di scope
  • Re: Ereditarietà e templati

    Sposta le implementazioni dei metodi delle classe nei corrispettivi file.h
    Il primo postulato dei template afferma che i metodi template vadano sviluppati nei rispettivi file .h e non in file.cpp

    (Che è quello che ho fatto per permettere la compilazione).
    Quanto detto finora riguardo i metodi virtuali è comunque giusto.
  • Re: Ereditarietà e templati

    Adesso me lo compila, grazie!
  • Re: Ereditarietà e templati

    Ho cantato vittoria troppo presto. Oggi quando ho provato a testarlo con il main mi dà ancora lo stesso problema. Posto main e le tre classi
    #include <iostream>
    #include "linkedList.h"
    #include "OrderedList.h"
    
    
    using namespace std;
    
    int main()
    {
        linkedList<int> myList;
        int n;
        cout << "Inserire una serie di valori interi(termina con -99): " << endl;
    
        cin >> n;
        while(n != -99)
        {
            myList.insert(n);
            cin >> n;
        }
    
        cout << endl;
        myList.print();
        return 0;
    }
    
    #ifndef LINKEDLIST_H
    #define LINKEDLIST_H
    
    #include "nodeType.h"
    #include <iostream>
    
    template <class Type>
    class linkedList
    {
        public:
            linkedList();
            ~linkedList();
            linkedList(const linkedList<Type>& other);
            linkedList& operator=(const linkedList<Type>& other);
            void destroyList();
            void initializeList();
            void print() const;
            virtual bool search(const Type& searchItem) const = 0;
            virtual void insertFirst(const Type& newItem) = 0;
            virtual void insertLast(const Type& newItem) = 0;
            virtual void deleteNode(const Type& nodetodel) = 0;
        protected:
            int count;
            nodeType<Type> *first;
            nodeType<Type> *last;
        private:
            void copyList(const linkedList<Type>& other);
    };
    
    template <class Type>
    linkedList<Type>::linkedList()    //ctor
    {
        first = NULL;
        last = NULL;
        count = 0;
    }
    
    template <class Type>
    linkedList<Type>::~linkedList()   //dtor
    {
        destroyList();
    }
    
    template <class Type>
    linkedList<Type>::linkedList(const linkedList<Type>& other)
    {
         first = NULL;
         copyList(other);
    }
    
    template <class Type>
    linkedList<Type>& linkedList<Type>::operator=(const linkedList<Type>& rhs)
    {
        if (this != &rhs)
            copyList(rhs);
    
        return *this;
    }
    
    template <class Type>
    void linkedList<Type>::destroyList()
    {
        nodeType<Type> *current;
    
        while(first!=NULL)
        {
            current = first;
            first = first->link;
            delete current;
        }
    
        last = NULL;
        count = 0;
    }
    
    template <class Type>
    void linkedList<Type>::initializeList()
    {
        destroyList();
    }
    
    template <class Type>
    void linkedList<Type>::print() const
    {
        nodeType<Type> *current;
    
        current = first;
    
        while(current != NULL)
        {
            std::cout << current->info;
            current = current->link;
        }
    }
    
    template <class Type>
    void linkedList<Type>::copyList(const linkedList<Type>& other)
    {
        nodeType<Type> *current;
        nodeType<Type> *newNode;
    
        if(first != NULL)
            destroyList();
    
        if(other.first == NULL)
            initializeList();
        else
        {
            current = other.first;
    
            count = other.count;
            first = new nodeType<Type>;
            first->info = current->info;
            first->link = NULL;
    
            last = first;
    
            current = current->link;
    
            while(current != NULL)
            {
                newNode = new nodeType<Type>;
                newNode->info = current->info;
                newNode->link = NULL;
    
                last->link = newNode;
                last = newNode;
    
                current = current->link;
            }
        }
    }
    #endif // LINKEDLIST_H
    #ifndef ORDEREDLIST_H
    #define ORDEREDLIST_H
    
    #include "linkedList.h"
    
    template <class Type>
    class OrderedList : public linkedList<Type>
    {
        public:
            bool search(const Type& searchItem) const;
            void insert(const Type& item);
            void deleteNode(const Type& nodetodel);
            void insertFirst(const Type& newItem);
            void insertLast(const Type& newItem);
        protected:
        private:
    };
    
    template<class Type>
    bool OrderedList<Type>::search(const Type& searchItem) const
    {
        bool found = false;
        nodeType<Type> *current;
        current = first;
    
        while(current != NULL && !found)
        {
            if(current->info >= searchItem)
                found = true;
            else
                current = current->link;
        }
    
        if(found)
            found = (current->info == searchItem);
    
        return found;
    }
    
    template<class Type>
    void OrderedList<Type>::insert(const Type& item)
    {
        nodeType<Type> *current; //pointer to traverse the list
        nodeType<Type> *trailCurrent; //pointer just before current
        nodeType<Type> *newNode;
    
        bool found;
        newNode = new nodeType<Type>; //create the node
        newNode->info = item; //store newItem in the node
        newNode->link = NULL; //set the link field of the node
        //to NULL
        if (first == NULL) //Case 1
        {
            first = newNode;
            last = newNode;
            count++;
        }
        else
        {
            current = first;
            found = false;
            while (current != NULL && !found) //search the list
                if (current->info >= item)
                    found = true;
                else
                {
                    trailCurrent = current;
                    current = current->link;
                }
    
            if (current == first) //Case 2
            {
                newNode->link = first;
                first = newNode;
                count++;
            }
            else //Case 3
            {
                trailCurrent->link = newNode;
                newNode->link = current;
                if (current == NULL)
                    last = newNode;
                count++;
            }
        }
    }
    
    template<class Type>
    void OrderedList<Type>::insertFirst(const Type& newItem)
    {
        insert(newItem);
    }
    
    template<class Type>
    void OrderedList<Type>::insertLast(const Type& newItem)
    {
        insert(newItem);
    }
    
    template<class Type>
    void OrderedList<Type>::deleteNode(const Type& nodetodel)
    {
        nodeType<Type> *current; //pointer to traverse the list
        nodeType<Type> *trailCurrent; //pointer just before current
        bool found;
    
        if (first == NULL) //Case 1
            std::cout << "Cannot delete from an empty list." << std::endl;
        else
        {
            current = first;
            found = false;
            while (current != NULL && !found) //search the list
                if (current->info >= nodetodel)
                    found = true;
                else
                {
                    trailCurrent = current;
                    current = current->link;
                }
    
            if (current == NULL) //Case 4
                std::cout << "The item to be deleted is not in the "
                          << "list." << std::endl;
            else
                if (current->info == nodetodel)
                {
                    if (first == current) //Case 2
                    {
                        first = first->link;
    
                        if (first == NULL)
                            last = NULL;
    
                        delete current;
                    }
                    else //Case 3
                    {
                        trailCurrent->link = current->link;
    
                        if (current == last)
                            last = trailCurrent;
    
                        delete current;
                    }
    
                    count--;
                }
    
                else //Case 4
                    std::cout << "The item to be deleted is not in the "
                              << "list." << std::endl;
        }
    }//end deleteNode
    
    #endif // ORDEREDLIST_H
    
    #ifndef NODETYPE_H
    #define NODETYPE_H
    
    template <class Type>
    struct nodeType
    {
        Type info;
        nodeType<Type> *link;
    };
    
    #endif // NODETYPE_H
    
  • Re: Ereditarietà e templati

    Beh, è normale se stai tentando di creare una classe astratta come linkedList.
    Se invece di linkedList usi OrderedList non hai il problema.
  • Re: Ereditarietà e templati

    No, in realtà ho subito corretto nel main la variabile myList dichiarandola come OrderedList e il problema persisteva. Cercando sul web ho trovato qualcosa del genere Al punto numero 7 penso si discuta del mio caso anche se non ho capito molto bene
  • Re: Ereditarietà e templati

    Hai provato a fare un rebuild completo? Perché confermo che io non ho errori di compilazione.

    Per quanto riguarda il link non mi pare che tu ricada in uno di quei casi.

    P.S. Che compilatore?
Devi accedere o registrarti per scrivere nel forum
17 risposte