Newsgroup: it.comp.lang.c++
Titolo: Classi

Perche' mi da l'errore:
"NULL, undecleared identifier" ?
E poi sempre sulla stessa riga:
'=' : cannot convert from 'int' to 'struct Heap::Struct*'
File lista.h:
#ifndef HEAP
#define HEAP
class Heap {
public:
	Heap(int);
	Heap(Heap&);
	~Heap(); 
	Heap& operator=(const Heap&);
	int& operator[](int); 
	void Inserisci(int);
	void Estrai();
	int MassimoElementi() {return dim;}
	int NumElementi() {return n;}
protected:
	int n;
	int dim;
private:
	void FaiSalire(int);
	void FaiScendere(int);
	void Scambia(int,int);
	struct Struct {
		int elemento;
		Struct* next;
	};
	Struct* vett;
};
#endif
File lista.cpp:
Heap::Heap(int dim) {
	int a=0;
	vett->next = NULL;  //ERRORE!!!!!!!!
	while (a <= dim-1) {
		Struct* temp;
		vett->next = temp;
		vett = vett->next;
		a++;
	}
	vett->next = NULL;  //ERRORE!!!!!!!
}
Heap::~Heap() {
}
Heap::Heap(Heap& h) {
	while (h.vett->next) {
		vett->elemento = h.vett->elemento;
		h.vett = h.vett->next;
	}
	vett->next = NULL;
}
void Heap::Scambia(int i,int j) {
	Struct* vett1 = vett;
	for (int a=0;a<i;a++) 
		vett1 = vett1->next;
	int temp = vett->elemento;
	for (int b=0;b<j;a++)
		vett = vett->next;
	vett1->elemento = vett->elemento;
	vett->elemento = temp;
}
void Heap::Inserisci(int e) {
	if (n<dim) {
		n++;
		while (vett->next)
			vett = vett->next;
		Struct* temp;
		temp->elemento = e;
		temp->next = NULL;
		vett->next = temp;
		FaiSalire(n);
	}
}
void Heap::FaiSalire(int e) {
	int b,c;
	if (e>1) {
		for (int a=1;a<e/2;a++)
			vett = vett->next;
		vett->elemento = b;
		for (int d=1;d<e;d++)
			vett = vett->next;
		vett->elemento = c;
		if (b<c) {
			Scambia(b,c);
			FaiSalire(e/2);
		}
	}
}
void Heap::FaiScendere(int e) {
	int b,figlio = e*2;
	if (figlio<n) {
		for(int a=1;a<figlio;a++)
			vett = vett->next;
		b = vett->elemento;
		if(vett->elemento>vett->next->elemento) {
			figlio++;
			b = vett->next->elemento;
		}
	}
	if(figlio<=n) {
		for (int c=1;c<e;c++) 
			vett = vett->next;
		if (vett->elemento<b) {
			Scambia(e,figlio);
			FaiScendere(figlio);
		}
	}
}
Heap& Heap::operator=(const Heap& h) {
	if(&h == this) 
		return* this;
	if (dim!=h.dim) {
		dim=h.dim;
		while(vett->next)
			vett = vett->next;
	    int* vettore;
		vettore = new int[h.dim];
		while(h.vett->next) {
			int i=0;
			vettore[i] = h.vett->elemento;
			i++;
		}
		int a=0;
		while (a == h.dim-1) {
		Struct* temp;
		vett->elemento = vettore[a];
		vett->next = temp;
		vett = vett->next;
		a++;
		}
		vett->elemento = vettore[a+1];
		vett->next = NULL;
		delete [] vettore;
		return* this;
	}
	return *this;
}
 
void Heap::Estrai() {
	if (n>0) {
		Struct* vett1 = vett;
		while(vett1->next) 
			vett1 = vett1->next;
		vett1->elemento = vett->elemento;
		for (int a=1;a<n-2;a++)
			vett = vett->next;
		delete vett->next->next;
		vett->next = NULL;
		FaiScendere(1);
	}
}

 '=' : cannot convert from 'int' to 'struct Heap::Struct*'
NULL e' una macro definita in alcuni header della
libreria standard.  Se non includi gli header giusti,
NULL non e' definito e il compilatore da errore.
Il secondo errore probabilmente salta fuori perche'
il compilatore, per tentare di andare avanti, interpreta
le cose sconosciute come int.
In C++, per indicare il puntatore nullo, di solito
si usa 0 (uno zero).  Se hai incluso gli header puoi
anche usare NULL (che e' definito come 0), ma il suo
uso e' stato sconsigliato perche' negli header del C
NULL spesso e' definito come ((void*)0), che non e'
una valido puntatore nullo in C++ (e non puo' essere
assegnato a un qualcosa*).
	Mauro

 
Perche' NULL non e' definito dal C++. Devi definirlo tu, o utilizzare
una libreria che lo includa. Prova
	#define NULL 0
o meglio se usi una costante.
-- 
Zack
Stefano Zacchiroli
zacc...@cs.unibo.it
za...@comune.budrio.bo.it
ICQ# 33538863
"Never understimate the dark side"

	vett->next = NULL;  //ERRORE!!!!!!!
Stesso problema di cui sopra...
Paolo
-----------------------------------------------------------------
  Paolo Marotta
  Computer Science, University of Pisa
  home:   
http://www.cli.di.unipi.it/~marotta
-----------------------------------------------------------------

 inconvenienti.
Scusa l'ignoranza, ma quali sono?
Probabilmente basterebbe guardare le FAQ, ma se avessi la cortesia (e il
tempo) di riassumermi i concetti principali, te ne sarei grato. Oppure
mandami ... a quel sito :)
--
Alessandro Monti

#endif



Non sono riuscito a trovare dove ho letto del problema...
sostanzialmente l'inconveniente principale e` che ci potrebbero essere
problemi di conversione legati al modo in cui la macro NULL e`
definita. L'uso di 0 garantisce invece che tale costante sia
convertita propriamente al puntatore nullo di tipo corretto.
Dal poco che ho visto sul draft dello standard, non c'e` un modo
univoco di definire NULL, possibili definizioni sono 0 oppure
0L... il draft esclude (void *) 0 ed afferma che tale definizione e`
dipendente dall'implementazione. Invece se non ricordo male
ogni implementazione deve garantire che 0 sia convertito al puntatore
nullo di tipo opportuno.
In effetti Scott Meyers nel suo Effective C++ mostra alcuni
possibili inconvenienti su NULL quando sconsiglia
l'overloading di funzioni che differiscono per un parametro
che in un caso e` int e nell'altro di tipo puntatore.
Personalmente uso sempre 0...


 che in un caso e` int e nell'altro di tipo puntatore.
Cioč, passando NULL, il compilatore non saprebbe se gli stai passando un int
(come la definizione di NULL suggerirebbe) oppure un puntatore "vuoto", e
probabilmente userebbe la funzione con l'int, potenzialmente molto diversa.
Grazie per la spiegazione.
Comunque penso che continuerņ ad usare NULL, a meno di grossi problemi: e
troppo comodo e leggibile per rinunciarvi dopo tanti anni di onesto
servizio, specialmente in C. (notti di debug risparmiate)
--
Alessandro Monti

Salve ragazzi,
sono nuovo del ng e diciamo che ho una modesta conoscenza del C++ sia per
studio all'università che per passione...vengo subito alla mia domanda, son
sicuro che mi darete un ottima risposta...Grazie!
Lo stesso problema che avete trovato per NULL in effetti ci sarebbe per
l'opposto e cioè l'infinito.Solo che NULL esiste e quindi si può usare ma un
token, una parola chiave,per infinito no, ci vorrebbe una specie di INFINITY
io in effetti uso typedef int INFINITY e poi la assegno a un valoro molto
alto...per esempio mi è servito nell'algoritmo di verifica se una struttura
di tipo albero è ordinata...avete altre soluzioni riguardo all'infinito...:)
itemtype max(btree *t)      // questa è la funziona che mi restituisce il
massimo elemento
                                        //  dei nodi dell'albero
    {
        itemtype temp,maxim;
        if(!t)maxim=-INFINITY;    // di solito uso il typedf in capo al file
ma non so se faccio bene
        else
        {
          maxim=t->item;
          temp=max(t->left);
          if(temp > maxim) maxim=temp;
             temp=max(t->right);
          if(temp > maxim) maxim=temp;
         }
        return maxim;
}
Grazie a chiunque risponda!
Computers are very sensible to air...
when you open windows they stop to work

servizio, specialmente in C. (notti di debug risparmiate)
Per tagliare la testa al toro puoi pensare di mettere un bel
#define NULL 0   /* o  0L */
come suggerito dallo standard.
Comunque se non ricordo male in caso di fallimento, new
restituisce 0 (e non NULL), oppure solleva l'eccezione
std::bad_alloc (a seconda dei casi).


 std::bad_alloc (a seconda dei casi).
Se non vado errato, new dovrebbe sollevare sempre std::bad_alloc e non
più restituire 0.
EMG

 di tipo albero è ordinata...avete altre soluzioni riguardo
all'infinito...:)
Ma non potevi postare un esempio di 4 righe? Di solito si posta una
semplificazione del problema, non un codice con l'implementazione di un
albero per spiegare l'utilizzo di una costante!
Comunque mi sembra che lo usi nel modo in cui di solito viene usato il
valore -1, ad indicare cioè un valore non permesso o l'impossibilità di
effettuare un'operazione.
Se i numeri negativi devono essere valori validi, forse sarebbe meglio fare
un controllo sul puntatore prima di chiamare la funzione.
Mi spiego meglio:
Immagino che tu chiami la funzione con qualcosa di simile:
valore = max(albero);
if (valore = -INFINITY)
    ...
else
    ...
E basterebbe invece chiamare con:
if (albero){
    valore = max(albero);
    ...
}else
    ...
Non credi sia almeno un po' più "pulito"?
--
Alessandro Monti

più restituire 0.
Mea culpa... hai perfettamente ragione. Il fallimento di new
provoca la chiamata a new_handler() che per default
solleva una eccezione std::bad_alloc.


io in effetti uso typedef int INFINITY 
caso mai userai
const int INFINITY = <qualcosa>;
oppure
#define INFINITY <qualcosa>
Anche in questo caso comunque ci sono problemi di conversione...
e poi per quello che si puo` farci conviene usare i limiti forniti
da STL.
