ho implementato la classe lista come clsse base e la classe lista con puntatori come classe derivata. nel test della classe, precisamente per quanto riguarda il metodo natural merge sort, ho un problema. posto le classi.

nodop.h
codice:
#include <iostream>
#include <stdlib.h>

using namespace std;

template<class tipoelem>
class nodop
{
   public:
      nodop();
      void setprec(nodop *);
      void setelem(tipoelem);
      void setsuc(nodop *);
      nodop *getprec();
      tipoelem getelem();
      nodop *getsuc();
   private:
      nodop *precedente;
      tipoelem elemento;
      nodop *successivo;
};

template<class tipoelem>
nodop<tipoelem>::nodop()
{
   precedente = NULL;
   elemento = 0;
   successivo = NULL;
}

template<class tipoelem>
void nodop<tipoelem>::setprec(nodop<tipoelem> *prec)
{
   precedente = prec;
}

template<class tipoelem>
void nodop<tipoelem>::setelem(tipoelem elem)
{
   elemento = elem;
}

template<class tipoelem>
void nodop<tipoelem>::setsuc(nodop<tipoelem> *succ)
{
   successivo = succ;
}

template<class tipoelem>
nodop<tipoelem> *nodop<tipoelem>::getprec()
{
   return(precedente);
}

template<class tipoelem>
tipoelem nodop<tipoelem>::getelem()
{
   return(elemento);
}

template<class tipoelem>
nodop<tipoelem> *nodop<tipoelem>::getsuc()
{
   return(successivo);
}
lista.h
codice:
#include <iostream>
#include <stdlib.h>

using namespace std;

template<class posizione, class tipoelem>
class lista
{
   public:
      virtual void crealista() = 0;
      virtual bool listavuota() = 0;
      virtual posizione primolista() = 0;
      virtual bool finelista(posizione) = 0;
      virtual posizione succlista(posizione) = 0;
      virtual posizione predlista(posizione) = 0;
      virtual tipoelem leggilista(posizione) = 0;
      virtual void scrivilista(posizione, tipoelem) = 0;
      virtual void inslista(posizione, tipoelem) = 0;
      virtual void canclista(posizione) = 0;
      
      void stampalista();
      void fondiordinate(lista &, lista &;
      void epurazione();
      void naturalmergesort();
   private:
      void distribuisci(lista, lista);
      void copiacatena(posizione &, lista, posizione &, lista &;
      void copia(posizione &, lista, posizione &, lista &, bool &;
      void merge(lista, lista, lista &, int &;
      void findicatena(posizione &, lista, posizione &, lista, posizione &, lista &;
      
};

template<class posizione, class tipoelem>
void lista<posizione, tipoelem>::stampalista()
{
   posizione p = primolista();
   while(!finelista(p))
   {
      cout << leggilista(p) << "\n";
      p = succlista(p);
   }
   cout << "\n";
}
   

template<class posizione, class tipoelem>
void lista<posizione, tipoelem>::fondiordinate(lista<posizione, tipoelem> &A, lista<posizione, tipoelem> &B)
{
   posizione pa = A.primolista();
   posizione pb = B.primolista();
   posizione pc = primolista();
   
   tipoelem elem1 = A.leggilista(pa);
   tipoelem elem2 = B.leggilista(pb);
   while(!A.finelista(pa) && !B.finelista(pb))
   {
      if(elem1 <= elem2)
      {
         inslista(pc, elem1);
         pa = A.succlista(pa);
      }
      else
      {
         inslista(pc, elem2);
         pb = B.succlista(pb);
      }
      elem1 = A.leggilista(pa);
      elem2 = B.leggilista(pb);
   }
   while(!A.finelista(pa))
   {
      inslista(pc, elem1);
      pa = A.succlista(pa);
      elem1 = A.leggilista(pa);
   }
   while(!B.finelista(pb))
   {
      inslista(pc, elem2);
      pb = B.succlista(pb);
      elem2 = B.leggilista(pb);
   }
}

template<class posizione, class tipoelem>
void lista<posizione, tipoelem>::epurazione()
{
   posizione p = primolista();
   posizione q;
   posizione t;
   while(!finelista(p))
   {
      q = succlista(p);
      while(!finelista(q))
      {
         if(leggilista(p) == leggilista(q))
         {
            t = succlista(q);
            canclista(q);
            q = t;
         }
         else
            q = succlista(q);
      }
      p = succlista(p);
   }
}

template<class posizione, class tipoelem>
void lista<posizione, tipoelem>::naturalmergesort()
{
   int numerocatene;
   lista<posizione, tipoelem> A, B, L;
   do
   {
      A.crealista();
      B.crealista();
      distribuisci(A, B);
      numerocatene = 0;
      crealista();
      merge(A, B, &L, &numerocatene);
   }while(numerocatene != 1);
}

template<class posizione, class tipoelem>
void lista<posizione, tipoelem>::distribuisci(lista<posizione, tipoelem> A, lista<posizione, tipoelem> B)
{
   posizione p = primolista();
   posizione pa = A.primolista();
   posizione pb = B.primolista();
   do
   {
      copiacatena(&p, this, &pa, &A);
      if(!finelista(p))
         copiacatena(&p, this, &pb, &B);
   }while(!finelista(p));
}

template<class posizione, class tipoelem>
void lista<posizione, tipoelem>::copiacatena(posizione &p, lista<posizione, tipoelem> L, posizione &pa, lista<posizione, tipoelem> &A)
{
   bool finecatena = false;
   do
      copia(&p, this, &pa, &A, &finecatena);
   while(!finecatena);
}

template<class posizione, class tipoelem>
void lista<posizione, tipoelem>::copia(posizione &p, lista<posizione, tipoelem> L, posizione &pa, lista<posizione, tipoelem> &A, bool &finecatena)
{
   tipoelem elemento = leggilista(p);
   A.inslista(pa, elemento);
   p = succlista(p);
   pa = succlista(pa);
   if(finelista(p))
      finecatena = true;
   else
      finecatena = (elemento > leggilista(p));
}

template<class posizione, class tipoelem>
void lista<posizione, tipoelem>::merge(lista<posizione, tipoelem> A, lista<posizione, tipoelem> B, lista<posizione, tipoelem> &L, int &numcatene)
{
   posizione p = primolista();
   posizione pa = A.primolista();
   posizione pb = B.primolista();
   
   while(!A.finelista(pa) && !B.finelista(pb))
   {
      fondicatena(&pa, A, &pb, B, &p, &L);
      numcatene++;
   }
   while(!A.finelista(pa))
   {
      copiacatena(&pa, A, &p, &L);
      numcatene++;
   }
   while(!B.finelista(pb))
   {
      copiacatena(&pb, B, &p, &L);
      numcatene++;
   }
}
listap.h
codice:
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include "lista.h"
#include "nodop.h"

using namespace std;

template<class tipoelem>
class listap : public lista<nodop<tipoelem> *, tipoelem>
{
   public:
      typedef nodop<tipoelem> *posizione;
      listap();                             //costruttore di default
      void crealista();                     //crea la lista vuota
      bool listavuota();                    //stabilisce se la lista è vuota o meno
      posizione primolista();               //restituisce la posizione del primo elemento della lista
      bool finelista(posizione);            //stabilisce se il nodo è l'ultimo della lista
      tipoelem leggilista(posizione);       //restituisce l'elemento della posizione specificata
      posizione succlista(posizione);       //restituisce la posizione del nodo successivo 
      posizione predlista(posizione);       //restituisce la posizione del nodo precedente
      void scrivilista(posizione, tipoelem);//scrive l'elemtno nel nodo specificato dalla posizione
      void inslista(posizione, tipoelem); //inserisce un nodo e scrive l'elemento nella posizione specificata 
      void canclista(posizione);          //elimina il nodo nella posizione specificata
   private:
      nodop<tipoelem> cella;                 //nodo della lista (nodo sentinella)
};

template<class tipoelem>
listap<tipoelem>::listap()
{
   crealista();                             //il costruttore invoca il metodo crealista
}

template<class tipoelem>
void listap<tipoelem>::crealista()
{
   cella.setprec(&cella);
   cella.setsuc(&cella);
   cella.setelem(0);
}

template<class tipoelem>
bool listap<tipoelem>::listavuota()
{
   return((cella.getprec() == &cella) && (cella.getsuc() == &cella));
}

template<class tipoelem>
typename listap<tipoelem>::posizione listap<tipoelem>::primolista()
{
   return(cella.getsuc());
}

template<class tipoelem>
bool listap<tipoelem>::finelista(typename listap<tipoelem>::posizione pos)
{
   return(pos == &cella);
}

template<class tipoelem>
tipoelem listap<tipoelem>::leggilista(typename listap<tipoelem>::posizione pos)
{
   return(pos->getelem());
}

template<class tipoelem>
void listap<tipoelem>::scrivilista(typename listap<tipoelem>::posizione pos, tipoelem elem)
{
   pos->setelem(elem);
}

template<class tipoelem>
typename listap<tipoelem>::posizione listap<tipoelem>::succlista(typename listap<tipoelem>::posizione pos)
{
   return(pos->getsuc());
}

template<class tipoelem>
typename listap<tipoelem>::posizione listap<tipoelem>::predlista(typename listap<tipoelem>::posizione pos)
{
   return(pos->getprec());
}

template<class tipoelem>
void listap<tipoelem>::inslista(typename listap<tipoelem>::posizione pos, tipoelem elem)
{
   posizione temp = new nodop<tipoelem>;
   
   temp->setprec(pos->getprec());
   temp->setsuc(pos);
   (pos->getprec())->setsuc(temp);
   pos->setprec(temp);
   temp->setelem(elem);
   pos = temp;
}

template<class tipoelem>
void listap<tipoelem>::canclista(typename listap<tipoelem>::posizione pos)
{
   posizione temp = pos;
   (pos->getsuc())->setprec(pos->getprec());
   (pos->getprec())->setsuc(pos->getsuc());
   pos = pos->getsuc();
   delete temp;
}
testlistap.cpp
codice:
#include "listap.h"
#include <iostream>
#include <stdlib.h>

using namespace std;

int main()
{
   listap<int> list, list2, list3, list4;
   listap<int>::posizione pos = list.primolista();
   listap<int>::posizione pos2 = list2.primolista();
   listap<int>::posizione pos4 = list4.primolista();
   int k;
   
   for(int i = 0; i < 10; i++)
   {
      list.inslista(pos, (100 - (i * 10)));
      pos = list.primolista();
   }
   
   for(int i = 0; i < 10; i++)
   {
      list2.inslista(pos2, (50 - (i * 5)));
      pos2 = list2.primolista();
   }

   list.stampalista();
   list2.stampalista();
   
   cout << "\n\n";
      
   list3.fondiordinate(list, list2);
   list3.stampalista();
   cout << "\n\n";
   list3.epurazione();
   list3.stampalista();
   
   cout << "\n\n";
   for(int i = 0; i < 10; i++)
   {
      cin >> k;
      list4.inslista(pos4, k);
      pos2 = list2.primolista();
   }
   list4.stampalista();
   list4.naturalmergesort();
   cout << "\n\n";
   list4.stampalista();
   
   system("pause");
   return 0;
}
il problema che mi viene visualizzato quando faccio il test della lista è il seguente:
114 C:\Dev-Cpp\esercizi\Lista\lista.h cannot declare variable `A' to be of type `lista<nodop<int>*, int>'
because the following virtual functions are abstract:

e si riferisce ai metodi virtali dichiarati nella classe base.
come posso risolvere questo problema???

per oregon: l'errore si riferisce alla riga 114 del metodo natural merge sort nella classe base lista.h