Newsgroup: it.comp.lang.c++
Titolo: ereditare da iostream

ciao a tutti,
avrei bisogno di creare una classe che eredita rispettivamente da
istream e da ostream, ma non sono riuscito a trovare alcuna indicazione
in merito ne' nello Stroustrup ne' nel Thinking in C++. Io non ho altre
fonti...
...guardare i sorgenti di fstream, stringstream e derivati non e` stato
per niente utile... sono troppo incasinati!
qualcuno puo` aiutarmi per piacere?
vi ringrazio,
andrea

 wrote in message
news:3C07C460...@edu.ph.unito.it...

spiega cosa vuoi fare. Derivare di per se è facile:
class C: public std::istream, public std::ostream {
};
comunque se quei sorgenti li trovi incasinati ... dubito che riuscirai a
fare quello che volevi fare, qualunque cosa sia.
--
Andrea Ferro
---------
Brainbench C++ Master. Scored higher than 97% of previous takers
Scores: Overall 4.46, Conceptual 5.0, Problem-Solving 5.0
More info 
http://www.brainbench.com/transcript.jsp?pid=2522556

 fare quello che volevi fare, qualunque cosa sia.
beh, questo francamente mi sembra un giudizio piuttosto affrettato
(oltreche' sbagliato).
di supponenza ce n'e` gia` abbastanza in giro, evitiamo..
ciao,
andrea

 venga utilizzato il mio concetto di inserimento?
Non certo ereditando da istream o da ostream. A parte che devi definire
meglio cosa intendi con "concetto di inserimento" direi che devi farlo
ridefinendo l'operator<< e l'operator>>.
Facciamo ordine.
istream e ostream sono solo dei typedef. Di fatto ostream altro non è
che basic_ostream<char,char_traits<char> > (naturalmente sto omettendo
per brevità la specifica del namespace).
La classe ostrem ha come unico scopo raccogliere un'insieme di funzioni
che servono da "helper" per gestire l'accesso ad uno stream di char.
Tale classe NON ha come scopo:
-) rappresentare lo stream (è compito di una classe derivata da
streambuf)
-) definire come si esegue l'I/O dei caratteri sullo stream (sempre
compito di una classe derivata da streambuf)
-) definire come formattare un dato (compito degli inserter)
Se lo stream non è uno stream di char ma di qualche cosa d'altro, usi
una diversa specializzazione del template.
Se invece lo stream è uno stream di caratteri ma vuoi cambiare il tipo
di stream nel senso che vuoi ridefinire in che modo un carattere viene
scritto (o letto) dallo stream devi ereditare da streambuf. In tal caso
potrebbe avere senso anche ereditare da istream e ostream e definire dei
costruttori che ti costruiscano tale stream. Un caso potrebbe essere una
classe che fa l'I/O su socket.
Il compito di trasformare un dato (un tipo) in una sequenza di caratteri
invece è affidato agli inserter. Ovvero agli operator<<. Se vuoi
cambiare il modo in cui la classe C è rappresentata da una sequenza di
caratteri devi ridefinire operator<<(ostream&,C&); che è la funzione che
si occupa di questo.


 potrebbe essere una classe che fa l'I/O su socket.
infatti, questo e` proprio quello che vorrei fare. 
la classe socket e` terminata da tempo. nell'uso e` del tutto simile ad
uno stream, ma costituendo un "tipo" a se', mi ha richiesto la stesura
di molti:
operator << (Socket, classe ) 
similissimi ai vari
operator << (ostream, classe )
di cui avevo gia` dotato le classi in questione..
vorrei evitare questi "doppi" e inquadrare il socket nell'ambito di uno
stream standard. 
dici quindi di rivolgere l'attenzione sugli streambuf?
dove posso trovare qualche informazione, o qualche esempio?
come ho detto: guardare l'implementazione della fstream e della
stringstream non mi e` servito, vorrei qualcosa anche di molto piu`
semplice da cui partire..
per ora ti saluto,
ciao
andrea

 infatti, questo e` proprio quello che vorrei fare. 
Dai un'occhiata ai seguenti due articoli:
http://www.cuj.com/current/feature.htm?topic=current
http://www.cuj.com/articles/2001/0110/0110a/0110a.htm?topic=articles
-- 
Posted from 
nts-03.mm.eutelsat.org
 [194.214.173.15] 
via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 semplice da cui partire..
Il problema è che capire come deve funzionare uno streambuf (e
implementarlo) è un casino immane (rispetto a capire come funzionano
istream e ostream). Quindi la difficoltà aumenterà, non diminuirà.
Non saprei dirti da dove partire. Io l'ho fatto una volta sola partendo
... dagli header del compilatore e praticamente senza neppure avere un
reference delle classi.
Oggi userei lo standard. Ma suppongo che ci sia in giro della
documentazione più "umana". Forse qualcun'altro saprà aiutarti.


 reference delle classi.
Come nota, esistono gia' delle classi che maneggiano sockets; io
consiglio la libreria "common c++" della free software foundation
(
http://www.gnu.org
; 
ftp://ftp.sunet.se/pub/gnu/commonc++
), che ha
classi per sockets e molte altre cose.  Perche' riinventare l'acqua
calda?
-- 
Maurizio Loreti                         
http://www.pd.infn.it/~loreti/mlo.html
Univ. of Padova, Dept. of Physics - Padova, Italy            
lor...@pd.infn.it

 calda?
Questo è un'altro discorso e la domanda va posta all'OP. Io l'unica
volta che mi trovai a implementare uno streambuff lo feci ai tempi del
DOS perchè mi serviva un IO seriale. Avevo scritto delle routine in
assembler (chiamabili e linkabili da C++) che mi gestivano l'UART a
basso livello via interrupt. Su queste avevo fatto una classe che veniva
usata da un'altra serie di classi che implementavano vari livelli di un
protocollo (handshake, correzione errore, ritrasmissione,
pacchettizzazione etc.) ed ero al punto di avere tutto incapsulato. In
pratica potevo fare delle write di buffer di lunghezza a piacere e stare
sicuro che venivano spezzati in pacchetti decorati con bit di parità
varia e CRC e quindi trasmessi e che il destinatario in caso di problemi
vari correggeva e dava un ACK e se non riusciva a correggere chiedeva la
ritrasmissione che avveniva automaticamente. In pratica ero al livello
in cui a comunicare sono direttamente le due applicazioni. (piccola
spiegazione: dall'altro lato non c'era un PC ma un sistema proprietario
basato su z80 e il cavo di trasmissione era spesso lungo parecchi metri,
di pessima qualità e ... passava in mezzo a campi magnetici piuttosto
"tosti". Ergo di errori ne capitavano continuamente a valanghe, da cui
la necessità, non potendo cambiare altre cose, di irrobustire i
protocolli). Dato che il corpo dell'applicazione era in C++ (prestandard
ovviamente) per uniformità di I/O (e per curiostà sul funzionamento
degli stream) decisi di implementare uno streambuf.
Tra l'altro mi dicono che tutti i protocollazzi sono stati
successivamente abbandonati ma lo streambuf e le routines a basso
livello sono sopravvissuti alla generazione successiva dell'HW (sempre
una UART era, ma a valle il circuito era proprietario e invece che su
rame con i livelli RS-232 il segnale viaggiava su fibra ottica. E
ovviamente dei campi magnetici se ne fregava altamente, quindi i
controlli di errore e la pacchettizzazione furono parecchio
"rilassati").


 documentazione più "umana". Forse qualcun'altro saprà aiutarti.
ne approfitto per chiederlo agli altri, dato che sono interessato. Dove 
trovare un po' di documentazione (possibilmente online) sugli streambuf 
e soprattutto sul come derivarne uno?
Sullo Stroustrup non c'e' moltissimo, Thinking in C++ ne accenna 
soltatno e non ho alcun altro testo.
ciao Anto
-- 
Antonio Cuni, 19 anni, studente
Brainbench C++ Master: 4.6, higher than 98% of all previous test takers.
C Language: 3.32, higher than 79% of all previous test takers.
Guida C/C++ di Programmazione.it: 
http://cpp.programmazione.it

 e soprattutto sul come derivarne uno?
Documentazione?  C'e' parecchio, IIRC, sullo Josuttis ("The C++
Standard Library, a tutorial and a reference") che pero' ora non ho
sottomano.
Ti basta un esempio?  Una volta ho scritto una classe che eredita da
streambuf in modo che tutto quello che finisce sullo stream va sia
sullo schermo che su un log file su disco.  L'essenziale lo trovi in
due snippets contenuti in 
http://wwwcdf.pd.infn.it/MLO/logout.tar.gz
 .
Ci sono due versioni; quella che preferisco e che ho usato
effettivamente e' la seconda (logout2.cxx).


 ciao Anto
Un ottimo libro sugli Iostreams e' quello di Angelica Langer
a Klaus Kreft: "Standard C++ IOStreams and Locales" di Addison Wesley
(2000). (Potresti chiedere alla biblioteca del Dipartimento di comprarlo ;-)
Spiega tra le altre cose come derivare da Streambuf ma da anche un sacco
di informazioni su locales e facets, argomenti trattati quasi da nessun
altro libro. 
Per quanto rigurarda il prolema specifico di ereditare da uno streambuf 
per usare gli operatori << e >> sui socket, c'e' un articolo sul
numero di Dicembre del C++ Users Journal che tratta proprio questo 
argomento. (Maciej Sobczak, "An Iostream-Compatible Socket Wrapper")
Purtroppo l'articolo non e' scaricabile dal sito cuj, ma puoi
trovare al seguente url i sorgenti allegati, che (una volta capito come 
funzionano gli streambuf) sono abbastanza chiari: 
ftp://192.215.71.135/pub/2001/1912/sobczak.zip
Saluti,
Fabio
-- 
Posted from 
flopiano.mm.eutelsat.org
 [194.214.173.28] 


 due snippets contenuti in 
http://wwwcdf.pd.infn.it/MLO/logout.tar.gz
 .
ok, ringrazio te e Fabio per le info.


ciao a tutti,
ho realizzato 'sto benedetto socketstream! tutto sembra funzionare alla
perfezione... con una piccola eccezione.
quando su un socketostream ci butto sopra un mio benalissimo vector2d,
avendo definito:
ostream &operator << (ostream &s, const vector2d &v )
{
	return s << "(" << v.x << "," << v.y << ")";
}
il relativo socketistream >> vect; fallisce miseramente.
dopo una piccola analisi, ho appurato anche al socketistream arriva una
stringa ben strana:
(,)xy
qualcosa del genere..... ma che senso ha?!
faccio presente con cout e cin questi operatori (<< e >>) funzionano
benissimo.
l'operatore >> e` il seguente (dallo stroustrup):
istream &operator >> (istream &s, Vector2d &v )
{
	bool success = false;
 
	char c = 0;
 
	s >> c;
	if (c == '(')
	{
		s >> v.x >> c;
 
		if (c == ',')	s >> v.y >> c;
		if (c == ')')	success = true;
	}
 
	if (!success) s.clear(std::ios_base::badbit);
 
	return s;
}
NOTARE:	se riscrivo l'operator << del vector come:
ostream &operator << (ostream &s, const vector2d &v )
{
	ostringstream str;
	str << "(" << v.x << "," << v.y << ")";
	return s << str.str();
}
tutto funziona alla perfezione.
faccio notare che l'operator << (ostream, complex) e` scritto usando
proprio questo sistema dell'ostringstream.
scrivendo una funzione che fa l'output senza ricorrere allo
stringstream, il mio povero socket fallisce pure nel trasmettere e
ricevere un complex.
perche' complicare le cose in questo modo?
ciao a tutti
andrea

 proprio questo sistema dell'ostringstream.
mi rifersisco agli operatori definiti in std per std::complex...