Saltar al contenido

¿Por qué necesitamos devolver la referencia a istream/ostream mientras sobrecargamos los operadores >> y

Mantén la atención porque en esta crónica encontrarás la solución que buscas.Esta sección fue probado por nuestros expertos para asegurar la calidad y veracidad de nuestro post.

Solución:

La razón es una combinación de varios hechos.

  1. Desea poder encadenar operaciones de entrada y salida como en

    in  >> x >> y;
    
    out << z << std::precision(10) << t << std::endl;
    

    por lo que debe devolver algo que le permita operator<< otra vez.

  2. Ya que desea que su operador trabaje en cualquier istreames decir, cualquier objeto derivado de std::istreamno se puede definir

    operator<<(istream_type, object);    // take istream by value
    

    ya que esto solo funcionaría para el tipo de istream específico istream_typepero no para un genérico istream. Para eso se debe usar polimorfismo, es decir tomar una referencia o un apuntador (que será una referencia o apuntador a una clase derivada de std::istream).

  3. Dado que solo tiene una referencia al istream, no puede devolver el objeto istream en sí mismo (que puede ser de un tipo que ni siquiera está definido en el punto de la definición de operator<<) pero solo la referencia que tienes.

    Se podría eludir esta restricción definiendo operator<< a template y tomar y devolver el istream_type por valor, pero eso requiere la istream type para tener un constructor de copia, que bien puede no tener por buenas razones.

  4. Para invocar el polimorfismo, en principio, se podrían usar punteros (a flujos) en lugar de referencias. Sin embargo, operator<<(stream*,const char*) no está permitido en C++ (al menos un operando debe ser de tipo clase o enumeración).

    Por lo tanto, con los punteros de flujo, uno debe usar la sintaxis de llamada a función y está de vuelta con el estilo C fprintf(stream*, args...).

    Además, los punteros pueden ser null o colgando, que de hecho es su estado predeterminado (cuando se declara sin inicializador), mientras que se puede asumir que una referencia es válida (no se puede declarar sin inicializador).

En este caso, cuando se devuelve la referencia, puede combinar el operador en una cadena. Por ejemplo

std::cout << "Hello " << "Rajat Verma";

Esto es equivalente a las siguientes llamadas del operador

operator <<( operator <<( std::cout, "Hello" ), "Rajat Verma" );
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
              returns reference to std::cout 

Una cosa más es que los objetos estándar ostream e istream, como cout y cin, usan constructores de copia privada, por lo que deben devolverse por referencia, no por valor.

Comentarios y calificaciones del tutorial

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *