OVH Cloud OVH Cloud

ostream qui absorbe tout

4 réponses
Avatar
Benoit Rousseau
Bonjour,
J'avez déjà demandé comment je pourrais faire un ostream qui absorbe tout :
> Par la même occasion, je voudrais un ostream qui absorbe tout ce qui
> lui arrive sans les traiter (un peu comme le /dev/null sous unix)
Ce flux serait utilisé dans une classe d'IO qui n'aurait pas besoin
d'output.

En lisant une autre discution sur les surchages d'ostreams, j'en suis
arrivé à la définition vide suivante :
class DumbBuf: public std::streambuf {
private:
std::streambuf* setbuf(char_type* s, std::streamsize n) {
return NULL;
}
int_type overflow(int_type c) {
return traits_type::not_eof( c ) ;
}
int sync() { return 0; }
};

class oDumbStream: private DumbBuf, public std::ostream {
public:
explicit oDumbStream( ) : std::ostream(this) {};
};

Est ce que c'est correct ?
Que fait la fonction overflow dans ce cas ? Quand est ce qu'elle est
appelée ?
Est ce que cette définition n'existe pas déjà dans la stl ?

4 réponses

Avatar
Michel Michaud
Dans news:3f9feb58$0$7729$, Benoit
Bonjour,
J'avez déjà demandé comment je pourrais faire un ostream qui
absorbe tout :


ofstream nul; // Pas ouvert !
nul << ... // Donc les « écritures » ne feront rien...

C'est pas suffisant ?

--
Michel Michaud
http://www.gdzid.com
FAQ de fr.comp.lang.c++ :
http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/

Avatar
kanze
"Michel Michaud" wrote in message
news:<lfSnb.2598$...
Dans news:3f9feb58$0$7729$, Benoit

J'avez déjà demandé comment je pourrais faire un ostream qui absorbe
tout :


ofstream nul; // Pas ouvert !
nul << ... // Donc les « écritures » ne feront rien...

C'est pas suffisant ?


Souvent. Ça dépend s'il passe le flux en tant que ostream& ailleurs. Si
oui, il a le problème que nul.bad() est vrai -- si l'ailleurs vérifie
l'état du flux, il va provoquer une erreur.

Le cas est rare. Si je maîtrise l'ailleurs complètement, je prends
parfois la risque, d'autant plus que cette solution supprime non
seulement les sorties, mais même le formattage. Si je ne maîtrise pas le
code à 100%, en revanche, je ne prends pas la risque -- le contrat d'un
ostream, c'est que le client a le droit de vérifier son état, et traiter
des erreurs comme des erreurs. Alors, j'utilise mon GB_NulStream, qui
ressemble en fait à ce qui a été proposé, avec en plus un buffer pour
éviter l'appel virtuel de underflow à chaque coup.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16


Avatar
Benoit Rousseau
wrote:
"Michel Michaud" wrote in message
news:<lfSnb.2598$...
Dans news:3f9feb58$0$7729$, Benoit
ofstream nul; // Pas ouvert !
nul << ... // Donc les « écritures » ne feront rien...


Souvent. Ça dépend s'il passe le flux en tant que ostream& ailleurs. Si
oui, il a le problème que nul.bad() est vrai -- si l'ailleurs vérifie
l'état du flux, il va provoquer une erreur.
Oui, il s'agit de ostream* qui change de comportement :

- vers un pipe si je suis en mode simulation
- rien si je suis en mode replay (il n'y a qu'un istream qui envoye les
les messages depuis un fichier dans ce cas).

nul.bad()


Pour le moment, je "maîtrise" tout le code, mais on ne sait jamais, des
fois que je n'y pense plus dans le futur

Alors, j'utilise mon GB_NulStream, qui
ressemble en fait à ce qui a été proposé, avec en plus un buffer pour
éviter l'appel virtuel de underflow à chaque coup.


N'y a t il pas moyen d'avoir un comportement similaire au "lasyness"
qu'on retrouve dans d'autres langages ? Parceque là, il y a toujours une
interprétation des operator<< ...


--------------------------------------------
Benoît Rousseau : roussebe at spray dot se
Jouez en programmant : http://realtimebattle.sourceforge.net/


Avatar
kanze
Benoit Rousseau wrote in message
news:<3fa69e54$0$22540$...
wrote:
"Michel Michaud" wrote in message
news:<lfSnb.2598$...
Dans news:3f9feb58$0$7729$, Benoit
ofstream nul; // Pas ouvert !
nul << ... // Donc les « écritures » ne feront rien...


Souvent. Ça dépend s'il passe le flux en tant que ostream& ailleurs.
Si oui, il a le problème que nul.bad() est vrai -- si l'ailleurs
vérifie l'état du flux, il va provoquer une erreur.


Oui, il s'agit de ostream* qui change de comportement :
- vers un pipe si je suis en mode simulation
- rien si je suis en mode replay (il n'y a qu'un istream qui envoye les
les messages depuis un fichier dans ce cas).

nul.bad()


Pour le moment, je "maîtrise" tout le code, mais on ne sait jamais,
des fois que je n'y pense plus dans le futur


En effet. Je trouve que c'est une solution à haute risque aussi. (Ce qui
n'empêche pas que je puisse m'en servir dans de petits programmes.)

Alors, j'utilise mon GB_NulStream, qui ressemble en fait à ce qui a
été proposé, avec en plus un buffer pour éviter l'appel virtuel de
underflow à chaque coup.


N'y a t il pas moyen d'avoir un comportement similaire au "lasyness"
qu'on retrouve dans d'autres langages ? Parceque là, il y a toujours
une interprétation des operator<< ...


Si tu veux aussi te passer du formattage, il faut utiliser un wrapper :

class OStreamWrapper
{
public:
OStreamWrapper( std::ostream* dest = NULL )
: myDest( dest )
{
}

template< typename T >
OStreamWrapper& operator<<( T const& type )
{
if ( myDest != NULL ) {
*myDest << type ;
}
return *this ;
}

std::ostream& getStream()
{
return myDest == NULL
? ourNulStream
: *myDest ;
}
private:
std::ostream* myDest ;
static NulOStream ourNulStream ;
}

Tant que tu fais des sorties vers le OStreamWrapper, il n'y aura
formattage que s'il y a réelement un flux attaché. La fonction getStream
est là afin avoir un flux classique pour passer aux fonctions déjà
existantes qui ne connaît pas ton wrapper -- dans ce cas-là, évidemment,
on ne peu pas éviter le formattage.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16