ciao a tutti, sto sempre sulla struttura ati insieme con lista di puntatori. ho un problema con il metodo unione che accetta come argomenti due insieme (passaggio per valore) e ne fa l'unione. nel primo ciclio il compilatore va in loop infinito ma non capisco perchè.

posto il codice che ho implementato.

listap.h
codice:
#ifndef listap_h
#define listap_h

#include "nodop.h"
#include "lista.h"
#include<iostream>
#include<stdlib.h>

using namespace std;

template<class tipoelem>
class listap : public lista<nodop<tipoelem> *, tipoelem>
{
   public:
      typedef nodop<tipoelem> *posizione;

      listap();
      void crealista();
      bool listavuota();
      posizione primolista();
      bool finelista(posizione);
      posizione predlista(posizione);
      posizione suclista(posizione);
      tipoelem leggilista(posizione);
      void scrivilista(posizione, tipoelem);
      void inslista(posizione, tipoelem);
      void canclista(posizione);
      
   private:
      nodop<tipoelem> sentinella;
};
#endif

template<class tipoelem>
listap<tipoelem>::listap() : lista<nodop<tipoelem> *, tipoelem>(1)
{
   this->crealista();
}

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

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

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

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

template<class tipoelem>
typename listap<tipoelem>::posizione listap<tipoelem>::predlista(typename listap<tipoelem>::posizione pos)
{
   if(pos->getprec() == (&sentinella))
      return(sentinella.getprec());
   else
      return(pos->getprec());
}

template<class tipoelem>
typename listap<tipoelem>::posizione listap<tipoelem>::suclista(typename listap<tipoelem>::posizione pos)
{
   if(pos->getsuc() == (&sentinella))
      return(sentinella.getsuc());
   else
      return(pos->getsuc());
}

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>
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); //il problema sta in questa istruzione
   pos->setprec(temp);
   temp->setelem(elem);
   pos = temp;
}

template<class tipoelem>
void listap<tipoelem>::canclista(typename listap<tipoelem>::posizione pos)
{
   posizione temp = new(nodop<tipoelem>);
   
   temp = pos;
   (pos->getprec())->setsuc(pos->getsuc());
   (pos->getsuc())->setprec(pos->getprec());
   pos = pos->getsuc();
   delete(temp);
}
insiemel.h
codice:
#ifndef insiemel_h
#define insiemel_h

#include<iostream>
#include<stdlib.h>
#include "listap.h"

using namespace std;

template<class tipoelem>
class insiemel
{
   public:
      insiemel();
      
      void creainsieme();
      bool insiemevuoto();
      bool appartiene(tipoelem);
      void inserisci(tipoelem);
      void cancella(tipoelem);
      void unione(insiemel, insiemel);
      void intersezione(insiemel, insiemel);
      void differenza(insiemel, insiemel);
      
      tipoelem getelem();
      //posizione getsuc(posizione);
      void visualizzainsieme();
   private:
      listap<tipoelem> *elementi;
};
#endif

template<class tipoelem>
tipoelem insiemel<tipoelem>::getelem()
{
   return(elementi->leggilista(elementi->primolista()));
}

template<class tipoelem>
void insiemel<tipoelem>::visualizzainsieme()
{
   elementi->stampalista();
}

template<class tipoelem>
insiemel<tipoelem>::insiemel()
{
   this->creainsieme();
}

template<class tipoelem>
void insiemel<tipoelem>::creainsieme()
{
   elementi = new listap<tipoelem>;
}

template<class tipoelem>
bool insiemel<tipoelem>::insiemevuoto()
{
   return(elementi->listavuota());
}

template<class tipoelem>
bool insiemel<tipoelem>::appartiene(tipoelem elem)
{
   bool trovato = false;
   typename listap<tipoelem>::posizione p = elementi->primolista();
   while((p != elementi->predlista(elementi->primolista())) && !trovato)
   {
      if(elementi->leggilista(p) == elem)
         trovato = true;
      else
         p = elementi->suclista(p);
   }
   return trovato;
}

template<class tipoelem>
void insiemel<tipoelem>::inserisci(tipoelem elem)
{
   if(!this->appartiene(elem))
      this->elementi->inslista(elementi->primolista(), elem);
}

template<class tipoelem>
void insiemel<tipoelem>::cancella(tipoelem elem)
{
   bool trovato = false;
   typename listap<tipoelem>::posizione p = elementi->primolista();
   while(!elementi->finelista(p) && !trovato)
   {
      if(this->getelem() == elem)
      {
         trovato = true;
         elementi->canclista(p);
      }
      else
         p = elementi->suclista(p);
   }
}

template<class tipoelem>
void insiemel<tipoelem>::unione(insiemel<tipoelem> A, insiemel<tipoelem> B)
{
   while(!A.insiemevuoto())
   {
      cout << "A.getelem() = " << A.getelem() << "\n";
      this->inserisci(A.getelem());
      A.cancella(A.getelem());
      system("pause");
   }
   while(!B.insiemevuoto())
   {
      this->inserisci(B.getelem());
      B.cancella(B.getelem());
   }
}

template<class tipoelem>
void insiemel<tipoelem>::intersezione(insiemel<tipoelem> A, insiemel<tipoelem> B)
{
   while(!A.insiemevuoto())
   {
      if(B.appartiene(A.getelem()))
         this->inserisci(A.getelem());
      A.cancella(A.getelem());
   }
}

template<class tipoelem>
void insiemel<tipoelem>::differenza(insiemel<tipoelem> A, insiemel<tipoelem> B)
{
   while(!A.insiemevuoto())
   {
      if(!B.appartiene(A.getelem()))
         this->inserisci(A.getelem());
      A.cancella(A.getelem());
   }
}
testinsiemel.cpp
codice:
#include "insiemel.h"
#include<iostream>
#include<stdlib.h>

using namespace std;

int main()
{
   insiemel<int> set;
   
   cout << "insiemevuoto() = " << set.insiemevuoto() << "\n";
   
   for(int i = 0; i < 10; i++)
      set.inserisci(i);
   
   cout << "insiemevuoto() = " << set.insiemevuoto() << "\n";

   cout << "appartiene(5) = " << set.appartiene(5) << "\n";
   cout << "appartiene(15) = " << set.appartiene(15) << "\n";
   
   
   set.cancella(5);
   cout << "appartiene(5) = " << set.appartiene(5) << "\n";
   set.visualizzainsieme();
      
   insiemel<int> set2;
   for(int i = 0; i < 10; i++)
      set2.inserisci(i * 2);
   set2.visualizzainsieme();
   system("pause");
         
   insiemel<int> set3;
   set3.unione(set, set2);
         system("pause");
   set3.visualizzainsieme();
   
   insiemel<int> set4;
   set4.intersezione(set, set2);
   set4.visualizzainsieme();
   
   insiemel<int> set5;
   set5.differenza(set, set2);
   set5.visualizzainsieme();
   
   system("pause");
   return 0;
}
come ho detto prima, nel metodo unione si va in loop infinito. perchè???