Newsgroup: it.comp.lang.c++
Titolo: Richiesta help su stream

Ciao, qualcuno puo' aiutarmi ?
Devo realizzare una classe, del tutto simile a ofstream, nella quale
intercettare (ma non rimpiazzare) il metodo open e l'operatore di
inserimento (<<).
Prima di ciascuna operazione devo fare una verifica architetturale e, se
necessario, chiudere il file corrente ed aprirne un altro.
class COdf : public basic_ofstream<char, char_traits<char> >
{
public:
	void open(const char *filename, ios_base::open_mode _M = out | trunc)
	{
		... miei controlli ...
		basic_ofstream<char, char_traits<char> >::open(filename), (openmode)_M);
	}
	COdf& operator<<(const char *_X)
	{
		... miei controlli ...
		... qualche cosa che scriva come << ...	
		return (*this);
	}
	COdf& operator<<(const int _X)
	{
		... idem come sopra ...
	}
	ecc.
};
come vedete utilizzo tranquillamente il metodo "open" originale di
basic_ofstream.
Allo stesso modo, se fosse un metodo anzichč un operatore,  mi piacerebbe
fare qualcosa del tipo:
                         basic_ostream<char, char_traits<char> >::operator
<< _X;
ovvero, utilizzare esplicitamente l'operatore nativo, senza ricorrere ad
una funzione aggiuntiva tipo write (come fa l'oggetto CDumpObject di
Microsoft) perchč questo mi impedirebbe di utilizzare i modificatori in
maniera trasparente ed in piů mi costringerebbe a passare per stringhe
intermedie.
Grazie a tutti per l'aiuto.
mic
--
Posted from 
net128-007.mclink.it
 [195.110.128.7]
via Mailgate.ORG Server - 
http://www.mailgate.org

necessario, chiudere il file corrente ed aprirne un altro.
Ma sei sicuro che la granularita` delle tue "verifiche architetturali"
debba essere quella del singolo "operator<<", non piu`, non meno?
E` normale che un dato operator<< ne chiami svariati altri, anche
in modo annidato; ad esempio, che so, un tipico idioma sarebbe:
    class MagnificiTre {
        int a, b, c;
    public:
        MagnificiTre(int a, int b, int c):a(a),b(b),c(c) {}
        ostream& emit(ostream&o) const {
            return o<<'{'<<a<<','<<b<<','<<c<<'}';  
        }
    };
    inline ostream& operator<<(ostream& o, const MagnificiTre&mt)
    {
        return mt.emit(o);
    }
E` proprio necessario che tu controlli le cose in modo che, ad
esempio, l'aperta graffa possa andare su di un dato file, le
cifre di ogni intero invece vadano sempre tutte sullo stesso
file, ma la chiusa graffa possa potenzialmente finire su di un
altro file ancora, ecc ecc?  E se l'utente, con identica semantica
dal suo punto di vista, chiamasse o.put('{') invece di o<<'{',
dovrebbe cambiare il tuo comportamento?  E per
    o.write("pippo",5);
rispetto a
    o<<"pippo";
...?
Normalmente, un controllo come quello che tu vuoi fare, se
serve, serve con un'altra granularita`, indipendente dal fatto
che l'utente usi operator<< o i vari altri modi per scrivere sullo
stream: granularita` di carattere, di sequenza di caratteri,
di linea, o cose del genere.  Ebbene, questo e` proprio quello
che puoi ottenere ereditando da _streambuf_ (e da ofstream,
se vuoi, solo per ridefinirne la open e garantire istallazione e
gestione dei tuoi streambuf, lasciando invece in pace i vari
operator<<).  Con override dei vari virtual protected del
basic_streambuf, puoi controllare quel che ti serve, e magari
incapsulare un altro streambuf "vero" (presumibilmente quello
che fa l'output sul tuo "file corrente") delegandogli tutte le
operazioni "vere" - esattamente il concetto di "streambuf
filtrante" che illustra Kanze nell'articolo suddetto.
Alex