Newsgroup: it.comp.lang.c++
Titolo: dov'è l'errore?

riporto il codice del file vettore.h mi aiutate a trovare l'errore?
Il messaggio è il seguente:
"Error E2235 vettore.h 56: Member function must be called or its
address taken in function Vettore<int>::copia(const Vettore<int> &)"
il compilatore non segnalava alcun errore prima che scrivessi il
codice del metodo "bubblesort".
Thank's ^_^
 
// file vettore.h
#ifndef VETTOREH
#define VETTOREH
 
#include "utilita.h"
 
template <class T>
class Vettore
{
 private:
 T* elementi;
 int i_min, i_max;
 
 public:
 bool ePresente;
 
 int f_min() const { return i_min; }   // restituisce l'indice minimo
del vettore
 int f_max() const { return i_max; } // restituisce l'indice massimo
del vettore
 
 void init (int imin, int imax);     // metodo di inizializzazione
 void copia(const Vettore& vc); // metodo di copia
 
 Vettore () { i_min=1; i_max=0; } // costruttore vettori nulli
 Vettore (int imn, int imx)           // costruttore vettori non nulli
 { init(imn, imx); }
 Vettore(const Vettore& vc) ;     // costruttore vettore per copia
profonda
 
 ~Vettore() { delete [] elementi; } // distruttore
 
 T& operator[] (int indice);                   // overloading
dell'operatore []
 const T& operator[] (int indice) const; // overloading dell'operatore
[] costante
 
 void riempi(); // metodo di inserimento
 void visualizza(); // metodo di visualizzazione
 void cerca (T elem); // metodo di ricerca - restituisce true se
presente
 
}; // fine def classe Vettore
 
template <class T>
void Vettore<T>::init(int imin, int imax)
{
 elementi=new T[imax - imin + 1];
 i_min=imin; i_max=imax;
}
 
template <class T>
Vettore<T>::Vettore(const Vettore<T>& vc)
{
 init(vc.f_min(), vc.f_max());
 copia(vc);
}
 
template <class T>
void Vettore<T>::copia(const Vettore<T>& vc)
{
 if (f_min() !=vc.f_min() || f_max!=vc.f_max())
  cerr << "indici incompatibili!";
 for (int i=f_min(); i<=f_max(); i++)
  (*this)[i]=vc[i];
}
 
template <class T>
T& Vettore<T>::operator[] (int indice)
{ return elementi[indice]; }
 
template <class T>
const T& Vettore<T>::operator[] (int indice) const
{ return elementi[indice]; }
 
template <class T>
void Vettore<T>::riempi()
{
 for (int i=f_min(); i<=f_max(); i++)
 { cout << "\nelemento [" << i  << "] : "; cin >> (*this)[i]; }
}
 
template <class T>
void Vettore<T>::visualizza()
{
 cout << "\ncontenuto del vettore:\n";
 for (int i=f_min(); i<=f_max(); i++)
 { cout << "\n\telemento [" << i << "]: " << (*this)[i]; }
}
 
template <class T>
void Vettore<T>::cerca (T elem)
{
 int j; ePresente=false;
 for (int i=f_min(); i<=f_max(); i++)
  if ((*this)[i]==elem) 
  { ePresente=true;
   j=i;
  }  
 
 if (ePresente==1) cout << "\nelemento trovato in posizione " << j;
 else cout << "\nelemento " << elem << " non presente!";
} 
 
template <class T>
void bubblesort(Vettore<T> vs)
{
 int j;
 for (int ind=vs.f_min(); ind<=vs.f_max()-1; ind++)
 { j=ind+1;
  if (vs[ind]>vs[j]) scambia(vs[ind],vs[j]);
 }
}
 
#endif;

Scusami, puo´ darsi che sbaglio nel chiedertelo ma siccome non riesco a
vedere l´errore potresti postare il tuo metodo bubblesort?
Maurus

Oooops,
scusami, il metodo bubblesort era in fondo al file ora l´ho visto.
Allora, ci sono 2 cose che vorrei dirti:
1) Hai il costruttore di copia di Vettore ma non hai l´operatore di
assegnamento ed ho visto che all´interno di copia() ne fai uso nel for:
for (int i=f_min(); i<=f_max(); i++)
  (*this)[i]=vc[i];
2) Perche´ passi il vettore per valore nel medodo bubblesort invece che per
riferimento?
Potrebbe essere il fatto che , passando per valore in bubblesort si ha la
chiamata al costruttore di copia il quale chiama init() e poi copia() che ha
il problema descritto al punto 1), quindi penso che risolvi o definendo
l´operatore di assegnamento per Vettore o cambiando l´argomento di
bubblesort in un riferimento al Vettore:
template <class T>
void bubblesort(Vettore<T> &vs)
Mauro

C´era anche un altro errore nella funzione:
template <class T>
void Vettore<T>::copia(const Vettore<T>& vc)
dove fai:
if (f_min() !=vc.f_min() || f_max!=vc.f_max())
devi cambiare in:
if (f_min() != vc.f_min() || f_max() !=vc.f_max())
Riassumendo....
1) cambia il precedente errore nella funzione copia.
2) implementa l´operatore di assegnamento :
template <class T>
Vettore<T>& Vettore<T>::operator=(Vettore<T>& vc)
{
init(vc.f_min(), vc.f_max());
copia(vc);
return *this;
}
3) cambia l´argomento della tua bubblesort in modo che sia un riferimento:
template <class T>
void bubblesort(Vettore<T> &vs)
4) qua ho dovuto commentare perche´non c´era la funzione scambia:
//if (vs[ind]>vs[j]) scambia(vs[ind],vs[j]);
Suppongo che sia nel file utilita.h
Ciao alla prossima
Mauro

 }
Dati i metodi init() e copia() e l'operatore di assegnamento sopra
definito, sarebbe sbagliato definire il copy ctor come:
template <class T>
Vettore<T>::Vettore(const Vettore<T>& vc)
{
  (*this)=vc;
}
Avevo fatto un po' di prove con una classe simile e qualcosa non
funzionava correttamente. Forse era perche' dimenticavo delle
inizializzazioni ma il dubbio mi e' rimasto...
Grazie 1k :)
--
Leo-Panda
email: 
leo-...@libero.it
ICQ#: 105550412

{ return elementi[indice]; }
Idem.
HTH
Andrea
--
Andrea Griffini, Programmer
http://www.netservers.com/~agriff

inizializzazioni ma il dubbio mi e' rimasto...
La cosa non funzionerebbe. Il problema e' che "copia" deve
lavorare che delle istanze gia' costruite... se tu chiamassi
l'operatore di assegnazione dal costrutture il risultato
e' che useresti l'array "elementi" senza averlo allocato.
Anche l'operatore di assegnazione e' sospetto... chiama
"init" su una istanza che gia' possiede dei dati; chi e'
che libera l'array attualmente puntato da "elementi" ?



http://www.netservers.com/~agriff
Hai ragione Andrea non ci avevo pensato.
Cosi´ andrebbe bene?
template <class T>
Vettore<T>& Vettore<T>::operator=(Vettore<T>& vc)
{
    i_min = vc.f_min();
    i_max = vc.f_max();
    copia(vc);
    return *this;
}
Ciao
Mauro

}
Hmmm... questo e' peggio; siamo passati dal memory
leak (anzi, object leak) allo sconfinamento.
Il problema e' che qui cambi gli estremi rendendoli
uguali a quelli di vc pero' l'array allocato resta
lo stesso. Immagina di creare un vettore con 3
elementi e in seguito assegnare a questo vettore un
vettore che di elementi ne ha 10... come prima cosa
tu cambieresti i limiti i_min e i_max ma il campo
"elementi" continuerebbe a puntare alla stessa area
di soli 3 elementi. A questo punto chiami "copia"
che scrive 10 elementi da un vettore all'altro...
BUM! ... hai sconfinato!
La versione di prima semplicemente "perdeva" un array
di oggetti (perdendo memoria e non chiamando il
distruttore su quelle istanze)... questa versione
invece potrebbe provocare devastazioni di ogni genere.


Andrea Griffini, Programmer
Ok allora risolviamo sia memory leak che sconfinamento con questo:
template <class T>
Vettore<T>& Vettore<T>::operator=(Vettore<T>& vc)
{
    delete []elementi;
    init(vc.f_min(), vc.f_max());
    copia(vc);
    return *this;
}
Inoltre anche la bubblesort era errata:
da cambiare
template <class T>
void bubblesort(Vettore<T> vs)
{
    int j;
    for (int ind=vs.f_min(); ind<=vs.f_max()-1; ind++)
    {
        j=ind+1;
        if (vs[ind]>vs[j]) scambia(vs[ind],vs[j]);
    }
}
in :
template <class T>
void bubblesort(Vettore<T> &vs)
{
   for (int i=vs.f_max(); i>=vs.f_min(); i--)
      for (int j=vs.f_min()+1; j<=i; j++)
         if (vs[j-1] > vs[j])
            swap(vs[j-1],vs[j]);
}
Ciao
Mauro