2010-02-19 9 views
23

Les références en ligne ont des descriptions plutôt brèves et vagues sur le but de std::iostream::sentry. Quand devrais-je me préoccuper de cette petite créature? Si c'est uniquement destiné à être utilisé en interne, pourquoi le rendre public?Quand devrais-je me préoccuper de std :: iostream :: sentin?

+0

Depuis quand un identifiant est-il un critter? Et ce n'est certainement pas peu! : D – Hogan

Répondre

12

La plupart des gens n'écriront jamais de code pour traiter la création d'objets de sentinelle. Un objet sentinelle est nécessaire lorsque/si vous extrayez des données de (ou insérez-les dans) le tampon de flux qui sous-tend l'objet de flux lui-même.

Tant que votre opérateur d'insertion/extraction utilise d'autres membres iostream/opérateurs de faire son travail, il ne pas doivent faire face à la création d'un objet guérite (parce que les autres opérateurs iostream vont créer et détruire des objets sentry au besoin).

+0

Ah, merci. Cela me semble le plus logique (en particulier la chose du tampon de flux sous-jacent).J'ai été étonné de voir pourquoi les exemples de manuels montrant comment écrire vos propres opérateurs de flux personnalisés ne mentionnaient jamais les objets de sentinelle. –

12

Il est utilisé chaque fois que vous avez besoin d'extraire ou de sortir des données avec un flux. C'est-à-dire, chaque fois que vous créez un operator>>, l'opérateur d'extraction, ou operator<<, l'opérateur d'insertion.

Son but est de simplifier la logique: «Y a-t-il des bits défectueux? Synchronisez les tampons Pour les flux d'entrée, optionnellement, supprimez les espaces vides.

Tous les opérateurs de flux d'extraction devrait commencer par:

// second parameter to true to not skip whitespace, for input that uses it 
const std::istream::sentry ok(stream, icareaboutwhitespace); 

if (ok) 
{ 
    // ... 
} 

Et tous les opérateurs de flux d'insertion doivent commencer par:

const std::ostream::sentry ok(stream); 

if (ok) 
{ 
    // ... 
} 

Il est juste un moyen plus propre de faire (quelque chose de similaire à):

if (stream.good()) 
{ 
    if (stream.tie()) 
     stream.tie()->sync(); 

    // the second parameter 
    if (!noskipwhitespace && stream.flags() & ios_base::skipws) 
    { 
     stream >> std::ws;    
    } 
} 

if (stream.good()) 
{ 
    // ... 
} 

ostream saute juste la partie espace.

+2

Si j'implémente un 'opérateur >>' en fonction d'autres fonctions de membre de flux, est-il toujours nécessaire (ou une bonne idée) d'utiliser la sentinelle? –

+0

Qu'en est-il de l'opérateur d'insertion? Ostream définit également la sentinelle. –

+0

@GMan: Je vous entends. Il semble que l'on puisse écrire tout un manuel sur les iostreams. :-) –

1

L'entrée formatée pour n'importe quoi sauf les types de base (int, double, etc.) n'a pas beaucoup de sens, et peut-être seulement à partir d'un flux non-interactif tel qu'un flux istrings. Donc, vous ne devriez probablement pas implémenter op >> en premier lieu, et donc ne pas avoir à vous soucier des objets sentinelle.

+0

Que se passe-t-il si je veux que l'opérateur de surcharge >> fasse une entrée formatée sur un nombre de types de base? Par exemple: 'struct Point {double x, double y}; Point de point; file >> point; 'L'opérateur surchargé >> est implémenté en termes d'opérateur >> pour les types de base. –

+0

@Emile Le point supposé est formaté comme "x, y", alors il est étonnamment difficile à implémenter op >> donc il fonctionne correctement pour le point ET fonctionne correctement lorsqu'il est utilisé de concert avec tous les autres opérateurs d'entrée formatés. Fondamentalement, il vaut mieux écrire des fonctions pour analyser les entrées spécifiques que vous attendez, plutôt qu'un schéma généralisé qui, à la fin de la journée, ne peut pas gérer les entrées du monde réel. –

+0

@Neil: Je vois ce que vous dites. Mais peut-être une utilisation légitime d'un opérateur personnalisé serait de lire des données à partir d'un fichier généré par des opérateurs symétriques. Cela semble être la prémisse derrière la bibliothèque Boost.Serialization. –