PDA

View Full Version : C++ estrattori e insertori


burohkr
10-01-2004, 12:01
ciao a tutti!!! sto' lavorando con una lista doppiamente allaciata
e tengo dei dubbi clamorosi.
non mi funziona l'insertore che ho dichiarato come friend nella classe lista e mi sto' ancora domandando perche' per esempio da questa funzione non ho accesso ai privati di nodo(lista e' dichiarata come classe friend di Nodo,..dato che per l'estrattore mi e' permesso e tiene la stessa dichiarazione piu' o meno).... credo che la soluzione sia nel riuscire a capire come poter accedervi..... avete degli esempi o aiuti????..... in verita devo usarlo(l'insertore ) per leggere dati da un file del disco, devo fare un while con il flusso di entrata fino che arrivi al carattere di fine file (che ho inserito con CTRL + D)......grazie

maxithron
10-01-2004, 13:01
Come hai garantito alla classe membro l'accesso alla classe contenitore?

Perchè tieni presente che friend non è ereditario e nemmeno transitivo.

/\/\@®¢Ø
10-01-2004, 18:25
C'e' qualche motivo per cui non usi la classe list (che e' appunto doppiamente allacciata) della libreria standard ? Ti risparmieresti un sacco di tempo di debug e con quella leggerere da file e' una sciocchezza.
Se hai un esempio dei dati che devi leggere posso mostrarti come si puo' fare.

maxithron
10-01-2004, 18:35
Originariamente inviato da /\/\@®¢Ø
C'e' qualche motivo per cui non usi la classe list (che e' appunto doppiamente allacciata) della libreria standard ? Ti risparmieresti un sacco di tempo di debug e con quella leggerere da file e' una sciocchezza.
Se hai un esempio dei dati che devi leggere posso mostrarti come si puo' fare.

Perdonami ma lui non dice di usarla la classe list?

/\/\@®¢Ø
10-01-2004, 20:18
Originariamente inviato da maxithron
Perdonami ma lui non dice di usarla la classe list?
Visto che dice di aver dichiarato l'inseritore "come friend nella classe lista" ho ritenuto che parlasse di una classe da lui scritta.
A parte che non capisco perche' la lista debba avere funzioni friend dei nodi (oggetti?) che contiene, una cosa soluzione molto semplice e' la seguente.


#include <list>
#include <iostream>
#include <algorithm> // o era <iterator> :confused: ?
using namespace std;

class Node{ /* blah */ };

istream& operator( istream& in , Node& n )
{ /* leggiamo in qualche modo un nuovo nodo da stream */ }

// blablabla ...

/* Legge da in i nodi e li mette in l */
void read_list( istream& in , list<Node>& l )
{
copy( istream_iterator<Node>(in) , istream_iterator() , back_inserter( l ) );
}

maxithron
11-01-2004, 01:50
In linea di massima si ma mi manca l'elemento principale.....ossia non mi è tanto chiara la richiesta dell'autore del 3D... :)

/\/\@®¢Ø
11-01-2004, 10:49
siamo in due :D

burohkr
12-01-2004, 13:44
non posso usare list. infatti la classe l'ho creata io.( non sono un esperto percio' se potete anche solo dirmi le cose piu' importanti dove dare un occhio in questi casi, ve ne sarei grato...... ho dichiarato lista come una classe friend per avere accesso agli elementi successivi e precedenti del nodo e per evitare intrusioni esterne...

burohkr
12-01-2004, 13:48
il fatto e' che non conosco altri modi... e' la prima volta che lavoro
in una lista doppia..... senza dichiarare friend la classe lista non potevo accedere ai privati del nodo, cioe' nodo* seguente, e nodo* precedente..... Ho anche dei problemi con il distruttore di nodo..... l'ho lasciato vuoto, pero' come faccio a distruggere i puntatori del nodo? Grazie di tutto ciao

/\/\@®¢Ø
12-01-2004, 14:15
Originariamente inviato da burohkr
il fatto e' che non conosco altri modi... e' la prima volta che lavoro
in una lista doppia..... senza dichiarare friend la classe lista non potevo accedere ai privati del nodo, cioe' nodo* seguente, e nodo* precedente..... Ho anche dei problemi con il distruttore di nodo..... l'ho lasciato vuoto, pero' come faccio a distruggere i puntatori del nodo? Grazie di tutto ciao

Scusami, ora capisco bene cosa intendevi dire.
In C++ una classe A e' friend della classe B quando A puo' accedere ai campi privati/protetti di B e si ottiene con la dicitura
"friend class A" all'interno della dichiarazione della classe B.
Nel tuo caso, supponendo che le due classi si chiamino "Nodo" e "Lista"
hai messo "friend class Lista" nella dichiarazione della classe Nodo ?
Ho il dubbio che tu abbia fatto il contrario.
Se ti e' possibile mostrare qualche spezzone di codice probabilmente ti potremo esseer di maggiore aiuto.

Il distruttore della classe Nodo dovrebbe solo distruggere il nodo a cui si riferisce, e lasciare che sia la classe lista a sistemare le relazioni

ad esempio con i tre nodi seguenti

A <--> B <--> C

se devi eliminare il nodo B prima aggiorni i nodi next di A e prev di C e poi fai un delete B che dovra' limitarsi a distruggere il nodo B

burohkr
13-01-2004, 13:57
il nodo e'....:
class Nodo {
public:
Nodo* ant()const;
Nodo* sig()const;
int dato()const;
void ant(Nodo*);
void sig(Nodo*);
void dato(int);
void mostrar();
friend class Lista;
friend istream& operator>>(istream& ,Nodo& );
void display(ostream& ) const;
friend ostream& operator<<(ostream& ,const Nodo& );
private:
int _dato;
Nodo* _sig;
Nodo* _ant;
Nodo(int = 0,Nodo* = NULL,Nodo* = NULL);
~Nodo();
};//Nodo


Questo era il mio vecchio nodo. pero' ora mi hanno detto che e' meglio non usare friend class lista per niente, dato che peggiora l'incapsulazione..... ora ti faccio vedere i miei insertore e estrattore
....vedi se mi puoi aiutare usando pero' solamente accedenti e modificatori della classe nodo o lista(come se non avessi dichiarato la classe lista amica di nodo....Adesso sto' usando un intero ma poi lo modifichero' con una persona, perche' la lista sara' un agenda di persone......
Ti ho anche messo le ipotetiche funzioni per scrivere su file e leggere da file.....(scrivere sembra che funziona ma dovro' cambiarlo per il motivo che ti ho detto all'inizio......e' scritto in spagnolo perche' mi trovo in spagna a studiare.... ciao e grazie

void Lista::guardar()
{
char eof[5];
char nombre[25];
cout<<"nombre del fichero con extension(MAX 25 char): "<<endl;
gets(nombre);
cout<<endl;
ofstream flujoSalida(nombre,ios::out);
if(!flujoSalida)
{
cerr<<"El fichero no se puede abrir"<<endl;
exit(1);
}//if
flujoSalida<<*this;
flujoSalida.open(nombre,ios::app);
cout<<"pulsar CTRL-D por continuar: ";
cin>>eof;
flujoSalida<<eof;
flujoSalida.close();
}


/******************************************************************************/
void Lista::display(ostream& out) const
{
Nodo* temp =_primero;
//recorremos la agenda y mostramos la persona que hay en
//cada posición del array
while(temp != NULL)
{
out<<temp->_dato;
out<<endl;
temp = temp->_sig;
}//while
}

/******************************************************************************/
ostream& operator<<(ostream& out,const Lista& lista)
{
lista.display(out);
return out;
}

/******************************************************************************/
istream& operator>>(istream& entrada,Lista& lista)
{
Nodo* temp = lista._primero;
while(entrada>>temp->dato()){
temp = temp->sig();
lista._cont++;
}
return entrada;
}


/******************************************************************************/
void Lista::recuperarFichero()
{
char nombre[25];
cout <<"Escriba el nombre del fichero(con extension) a recuperar: "<<endl;
gets(nombre);
ifstream flujoEntrada(nombre,ios::in);
if(!flujoEntrada)
{
cerr<<"error"<<endl;
exit(1);
}//if
flujoEntrada>>(*this);
cout<<endl;
cout<<"****************************************"<<endl;
cout<<"* Datos almacenados en memoria(agenda) *"<<endl;
cout<<"****************************************"<<endl;
}

/* es el cuerpo del destructor, pero lo pongo aqui para ahorrar cidigo
* ganando tambien lejibilidad
******************************************************************************/