2010-02-19 11 views
23

Las referencias en línea tienen descripciones bastante breves y vagas sobre el propósito de std::iostream::sentry. ¿Cuándo debería preocuparme por esta pequeña criatura? Si solo está destinado a ser utilizado internamente, ¿por qué hacerlo público?¿Cuándo debería preocuparme por std :: iostream :: centinela?

+0

¿Desde cuándo es un identificador una criatura? ¡Y ciertamente no es poco! : D – Hogan

Respuesta

12

La mayoría de las personas nunca escribirá ningún código que necesite tratar con la creación de objetos centinela. Se necesita un objeto centinela cuando/si extrae datos de (o lo inserta) en el almacenamiento intermedio de flujo que subyace al objeto de flujo en sí.

Mientras su inserción/operador de extracción utiliza otros miembros de iostream/operadores para hacer su trabajo, lo hace no tener que lidiar con la creación de un objeto de centinela (porque esos otros operadores iostream crearán y destruir objetos de centinela, según sea necesario)

+0

Ah, gracias. Esto tiene más sentido para mí (especialmente la cosa del buffer de transmisión subyacente).Estaba desconcertado sobre por qué los ejemplos de libros de texto que muestran cómo escribir tus propios operadores de flujo personalizados nunca mencionaron los objetos centinela. –

12

Se utiliza siempre que necesite extraer o extraer datos con una secuencia. Es decir, siempre que realice un operator>>, el operador de extracción o operator<<, el operador de inserción.

Su objetivo es simplificar la lógica: "¿Se han configurado los bits de falla? Sincronizar los búferes. Para las transmisiones de entrada, opcionalmente quite cualquier espacio en blanco del camino. De acuerdo, ¿listo?"

Todos los operadores de flujo de extracción deben empezar con:

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

if (ok) 
{ 
    // ... 
} 

Y todos los operadores de flujo de inserción deben empezar con:

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

if (ok) 
{ 
    // ... 
} 

Es sólo una forma más limpia de hacer (algo parecido a):

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 simplemente se salta la parte de espacios en blanco.

+2

Si implemento un 'operador >> personalizado en términos de otras funciones de miembros de flujo, ¿sigue siendo necesario (o una buena idea) usar el centinela? –

+0

¿Qué pasa con el operador de inserción? ostream también define centinela. –

+0

@GMan: te escucho. Parece que uno podría escribir todo un libro de texto solo en iostreams. :-) –

1

La entrada formateada para todo menos los tipos básicos (int, double, etc.) no tiene mucho sentido, y podría decirse que solo de ellos cuando se toma de un flujo no interactivo, como un istringstream. Entonces, probablemente no deberías estar implementando op >> en primer lugar, y por lo tanto, no tendrás que preocuparte por los objetos centinela.

+0

¿Qué pasa si quiero que el operador de sobrecarga >> haga una entrada formateada convenientemente en una tupla de tipos básicos? Por ejemplo: 'struct Point {double x, double y}; Punto de punto; file >> point; 'El operador sobrecargado >> se implementa en términos de operador >> para tipos básicos. –

+0

@Emile El punto de suposición está formateado como "x, y" luego es sorprendentemente difícil de implementar op >> por lo que funciona correctamente para el punto Y funciona correctamente cuando se utiliza en concierto con todos los demás operadores de entrada formateados. Básicamente, es mejor que escribas funciones para analizar las entradas específicas que estás esperando, en lugar de un esquema generalizado que al final del día no puede manejar las entradas del mundo real. –

+0

@Neil: Veo lo que dices. Pero quizás un uso legítimo de un operador personalizado >> sería leer los datos de un archivo generado por el operador simétrico << 's. Esta parece ser la premisa detrás de la biblioteca Boost.Serialization. –

Cuestiones relacionadas