sobrecarga de operadores y e/s en...

78
Sobrecarga de Operadores y E/S en C++ Antonio LaTorre de la Fuente

Upload: phamquynh

Post on 29-Apr-2018

215 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Sobrecarga de Operadores y���E/S en C++

Antonio LaTorre de la Fuente

Page 2: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Índice •  Sobrecarga de Funciones

•  Sobrecarga de Operadores

•  Entrada/Salida sobre streams básicos

•  Entrada/Salida sobre streams de fichero

•  Entrada/Salida sobre streams de cadena

Page 3: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Sobrecarga de Funciones

• Nuevo con respecto a C

•  Funciones con el mismo nombre pero distinto prototipo: número y/o tipo de argumentos

•  Útil si se quiere poder realizar una misma operación sobre distintos tipos de datos

Page 4: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Sobrecarga de Funciones void print (double number) {cout << number << endl;}

void print (int number) {cout << number << endl;}

void print (int number, string s = “hola”) {

cout << number << “, “ << s << endl;

}

Page 5: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Ambigüedad •  ¿Qué pasa si incluimos en nuestro código…?

unsigned num = 3;

print (num);

•  El compilador no sabe a qué función llamar: func_over.cc:18: error: call of overloaded ‘print(unsigned int&)’ is ambiguous

func_over.cc:6: note: candidates are: void print(int)

func_over.cc:7: note: void print(int, std::string)

func_over.cc:8: note: void print(double)

Page 6: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Ambigüedad •  Se soluciona usando static_cast

unsigned num = 3;

print (static_cast<double>(num));

•  ¿Qué pasaría si hiciéramos…?

int num = 3;

print (num);

Page 7: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Name Mangling •  Estrategia que usa el compilador para poder

diferenciar dos funciones con el mismo nombre int f (void) {return 1;}

int f (int) {return 0;}

void g (void) {int i = f (), j = f (0);}

•  Esto se traduciría en:

int __f_v (void) {return 1;}

int __f_i (int) {return 0;}

void __g_v (void) {int i = __f_v (), j = __f_i (0);}

Page 8: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Índice •  Sobrecarga de Funciones

•  Sobrecarga de Operadores

•  Entrada/Salida sobre streams básicos

•  Entrada/Salida sobre streams de fichero

•  Entrada/Salida sobre streams de cadena

Page 9: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

•  Lista de operadores válidos en C++

•  Se declaran de la siguiente forma:

tipo operator operador([argumentos])

Operadores en C++

+ - * / % ^ & |

~ ! , = < > <= >=

++ -- << >> == != && ||

+= -= *= /= %= ^= &= |=

<<= >>= [] () -> ->* new delete

Page 10: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Operadores en C++ •  Hay algunos operadores especiales que no

pueden ser sobrecargados

•  :: (resolución de ámbito)

•  . (selección de un miembro)

•  .* (selección de un miembro referenciado por un puntero)

•  ?: (operador condicional)

•  sizeof (tamaño de)

•  typeid (identificación del tipo)

Page 11: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Precedencia de Operadores

•  Los operadores en C++ tienen distinta precedencia, y a veces no es obvio

•  Lo mejor es usar () en casa de no estar seguro

•  Tabla de precedencias:

Inglés: http://www.cplusplus.com/doc/tutorial/operators/

Español: http://es.wikipedia.org/wiki/Operadores_en_C_y_C%2B%2B

Page 12: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Sobrecarga de operadores •  Podemos sobrecargar tanto operadores unarios

como binarios

tipo_ret operator op_unario (tipo1 arg1);

tipo_ret operator op_binario (tipo1 arg1, tipo2 arg2);

•  En este caso, ambos argumentos se muestran de manera explícita

Page 13: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Sobrecarga de operadores •  Ambas notaciones son equivalentes

C operator- (C n) {…}

C operator- (C n, C m) {…}

int main (void) {

C a, b, c, d;���c = -b;���d = b – a;

}

int main (void) {

C a, b, c, d;���c = operator- (b);���d = operator- (b, a);

}

Page 14: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Sobrecarga de operadores •  Si los operadores son métodos de una clase, uno

de los argumentos es implícito (aquél que invoca al operador)

class C {

public:

C operator- ();���C operator- (C);

}

Page 15: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Sobrecarga de operadores •  Estas dos notaciones son equivalentes

int main (void) {

C a, b, c, d;

c = -b;

d = b – a;

}

int main (void) {

C a, b, c, d;

c = b.operator-();

d = b.operator-(a);

}

Page 16: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Sobrecarga de operadores •  Ejemplo: Números Complejos

class Complejo {

public: ���Complejo (double r, double i) : real(r), imag(i) {}���…

private: ���double real;���double imag;

}

Page 17: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Operadores Aritméticos •  Suma de números complejos:

Complejo Complejo::operator+ (const Complejo& z2) const {

Complejo res (0, 0);

res.real = this->real + z2.real;���res.img = this->img + z2.img;

return res;

}

Page 18: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Operadores Relacionales •  Comparación de números complejos:

bool Complejo::operator== (const Complejo& z2) const {

return this->real == z2.real && this->imag == z2.imag;

}

Page 19: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Operadores de auto-incremento

•  Son operadores unarios

•  Permiten pre-incrementar y post-incrementar el valor de una variable

Pre-incremento: C C::operator++()

Post-incremento: C C::operator++(int x) Complejo Complejo::operator++() {

real += 1;���return *this;

}

Page 20: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Funciones “Amigas” •  Son funciones ajenas a una clase que pueden

acceder a los elementos privados de esa clase

•  Ejemplo:

•  Tenemos dos clases: Vector y Matriz

• Queremos definir el producto vectorial entre ambas clases

•  El contenido de los objetos es privado

Page 21: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Funciones “Amigas” class Vector {

friend operator* (const Matriz& matriz, const Vector& vector);

public:

private: ���int size;���int* data;

}

class Matriz {

friend operator* (const Matriz& matriz, const Vector& vector);

public:

private: ���int rows, columns;���int** data;

}

Vector operator* (const Matriz& matriz, const Vector& vector) {…}

Page 22: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Operadores de asignación •  Se sobrecargan para evitar la copia binaria de

objetos class Vector {

public: ���Vector& operator= (const Vector& vector) {��� size = vector.size;��� data = new int[vector.size];��� for (unsigned i = 0; i < size; i++) ��� data[i] = vector.data[i];��� return *this;��� }

private: ���int size;��� int* data;

}

class Vector {

public: ���Vector& operator= (const Vector& vector) {��� size = vector.size;��� data = vector.data;��� return *this;��� }

private: ���int size;��� int* data;

}

Page 23: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Operadores de inserción y extracción

•  Permiten escribir / leer en la salida / entrada estándar

•  Hay que sobrecargar los operadores:

ostream& operator<< (ostream& os, const T& arg)

istream& operator>> (istream& is, T& arg)

•  Podemos hacer que estos métodos sean amigos de nuestra clase o implementar un método público que imprima los datos

Page 24: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Operadores de inserción y extracción

class Complejo {

public: ��� void printComplejo(ostream & os);���…

private: ���double real;���double imag;

}

ostream& operator<< (ostream& os, const Complejo& c) {

c.printComplejo(os);���return os;

}

class Complejo {

public: ���friend ostream& operator<< (ostream& os, const Complejo& c);���…

private: ���double real;���double imag;

}

ostream& operator<< (ostream& os, const Complejo& c) {

os << c.real << …

}

Page 25: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Operador de Indexación •  Es el operador []

•  Es un operador binario y de clase: recibe el objeto donde se aplica y el índice facilitado

•  Útil, p.ej., para acceso seguro a datos: int Vector::operator[] (int i) {

if (i >= 0 && i < this->size) ��� return data[i];���else {��� cout << “Posición incorrecta: “ << i << endl;��� return 0;���}

}

Page 26: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Conversión de tipos •  Hay dos posibilidades para llevar a cabo

conversiones entre tipos definidos por el usuario:

•  Los constructores de conversión

•  Los operadores de conversión

•  Son útiles para hacer, por ejemplo:

Complejo a (2, 3), b (0, 0);

b = a + 5;

Page 27: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Constructores de conversión

•  Hay que añadir un constructor que nos permita crear el objeto a partir de un objeto del tipo que queramos convertir

class Complejo {

public: ���Complejo (double r, double i) : real(r), imag(i) {}���Complejo (int r) : real(r), imag(0) {}���Complejo operator+ (const Complejo& z2) const;���…

private: ���double real, imag;

}���

Complejo a (2, 3), b (0, 0); b = a + 5;

Page 28: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Operadores de conversión •  Se usan para proporcionar una conversión de un

tipo de usuario a otro tipo (de usuario o no)

•  Tiene la sintaxis:

C::operator T();

•  Donde C es el tipo de usuario que queremos convertir y T es el tipo en el que queremos convertir C

Page 29: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Operadores de conversión class Complejo {

public: ���Complejo (double r, double i) : real(r), imag(i) {}���operator double() {return real;}���Complejo operator+ (const Complejo& z2) const;���…

private: ���double real, imag;

}

Complejo a (2, 3); double b = a + 5; double c = a.operator double() + 5; double d = static_cast<double>(a) + 5;

Page 30: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Ambigüedades en la conversión

class Complejo {

public: ���Complejo (double r = 0, double i = 0) ���: real(r), imag(i) {}������operator double() {return real;}���Complejo operator+ (const Complejo& z2) const;���…

private: ���double real, imag;

}���

Complejo a(2, 3), c(0,0); double b = 5; c = a + b;

El compilador no sabe si convertir “b” a “Complejo” y realizar la suma o convertir “a” a “double”, hacer la suma y convertir el resultado a Complejo.

Surgen si hay varias conversiones implícitas posibles

Page 31: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Operador de llamada a función

•  Es el operador ()

•  Siempre debe ser definido dentro de una clase

•  x (y, z) se interpreta como x.operator (y, z)

•  Útil para implementar callbacks (pasar código como argumento de una función). Los denominados Objetos Función

•  También para el acceso a matrices multidimensionales

Page 32: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Operador de llamada a función class Inicializar {���

private: ��� double val;���public: ��� Inicializar (double x = 0) : val(x) {}��� void operator() (Vector& v);

}; void Inicializar::operator() (Vector& v) { for (unsigned i = 0; i < vector.size(); i++) v[i] = this->val;

} int main (void) { Vector v(5); Inicializar ini(1); ini(v);

}

Page 33: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Operador new •  Al reservar memoria con new y new[] se invoca a las

funciones operator new y operator new[]:

void* operator new (size_t tamaño); void* operator new[] (size_t tamaño);

•  Estas funciones reservan y memoria y luego llaman el constructor correspondiente

•  Se pueden sobrecargar para una clase C:

void* C::operator new (size_t tamaño); void* C::operator new[] (size_t tamaño);

•  Son funciones estáticas aunque no se declaren como tal (static), porque se invocan antes que el constructor

•  Primero se busca en la clase (y clases base) y luego la global

Page 34: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Operador new void* Vector::operator new (size_t tam) { reservarMemoria (tam, 0);

} void* Vector::operator new[] (size_t tam) { reservarMemoria (tam, 0);

} void* Vector::reservarMemoria (size_t tam, char c) { void* p = malloc (tam);

if (p == 0) { cout << “Error reservando memoria.” << endl; exit(-1); }

memset (p, c, tam); return p;

}

Page 35: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Operador delete •  Al liberar memoria con delete y delete[] se invoca a las

funciones operator delete y operator delete[]:

void operator delete (void*); void operator delete[] (void*);

•  Estas funciones llaman al destructor y luego liberan la memoria del objeto

•  Se puede sobrecargar para una clase C:

void C::operator delete (void*, [size_t]); void C::operator delete[] (void*, [size_t]);

•  Son funciones estáticas aunque no se declaren como tal (static), porque se invocan después del destructor

•  Primero se busca en la clase (y clases base) y luego la global

Page 36: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Operador delete void Vector::operator delete (void* p, size_t tam) { if (p) memset (p, 0, tam); free (p);

} void Vector::operator delete[] (void* p, size_t tam) { if (p) memset (p, 0, tam); free (p);

}

Page 37: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Índice •  Sobrecarga de Funciones

•  Sobrecarga de Operadores

•  Entrada/Salida sobre streams básicos

•  Entrada/Salida sobre streams de fichero

•  Entrada/Salida sobre streams de cadena

Page 38: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Visión General de la E/S en C++

•  Streams y Buffers •  Especializaciones según el tipo de operación y el origen/destino de los datos

Page 39: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Clases istream y ostream •  Derivan de la clase ios

•  Deben ser conectadas a un buffer (del tipo que sea)

•  cin y cout son de tipo istream y ostream

• Normalmente, para hacer E/S sobre ficheros o cadenas se usan las clases especializadas, pero se podrían usar estas clases básicas

•  Para usarlas: #include <iostream>

Page 40: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Clases istream y ostream •  Los Manipuladores nos permiten cambiar las

opciones de formato de los streams (#include <iomanip>)

•  Son funciones especialmente diseñadas para trabajar junto con los operadores de inserción (<<) y extracción (>>)

•  Se modifica el formato encadenándolos al objeto que representa el stream

cout << hex << showbase << 20 << endl;

Page 41: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Clases istream y ostream • Manipuladores sin parámetros: ���

(no)boolapha: Mostrar booleanos como true y false ���(no)showbase: Mostrar prefijo de tipo (0x, 0, etc.) ���(no)showpoint: Forzar la escritura del punto decimal ���(no)showpos: Forzar la escritura de un ‘+’ para valores positivos���(no)skipws: Permite ignorar caracteres de espaciado���(no)unitbuf: Forzar el vaciado del buffer tras cada operación���(no)uppercase: Mostrar caracteres alfabéticos en mayúsculas���dec, hex, oct: Cambiar base (decimal, hexadecimal y octal) ���fixed, scientific: Usar notación de coma fija o científica���internal, left, right: Alinear el texto���endl, ends, flush: Finalizar línea, cadena y vaciar buffer ���

Page 42: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Clases istream y ostream • Manipuladores con parámetros���

setprecision (int): Fija la precisión en coma flotante���setw (int): Fija el tamaño de un campo (que se rellena��� automáticamente en caso de ser necesario) ���setfill (char): Selecciona el carácter para el relleno���setbase (int): Fija la base numérica a usar (8, 10 ó 16) ���setiosflags (mask): Fija cualquiera de los anteriores flags���resetiosflags (mask): Reinicia los flags a los valores por defecto���

• Otra forma de hacer lo mismo •  Manipuladores sin parámetros: métodos setf y unsetf •  Manipuladores con parámetros: métodos propios (fill, width,

precision, etc.)

Page 43: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Clases istream y ostream •  Ejemplos cout << fixed << setprecision(5) << setw(10) << setfill(‘*’) << 2.87 << endl;

cout.setf(ios::fixed); cout.precision(5); cout.width(10); cout.fill(‘*’); cout << 2.87 << endl;

•  Ambas imprimen el mismo resultado���***2.87000

Page 44: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Clase ostream •  Permite hacer operaciones de escritura con y sin

formato

•  Sin formato: put y write

•  Con formato: operator<<

•  Permite manejar distintas situaciones de error

•  También se puede posicionar el puntero de escritura en posiciones determinadas del flujo de salida

Page 45: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Clase ostream •  La sobrecarga del operador de inserción permite

realizar escritura con formato

•  Se puede sobrecargar para cualquier tipo

ostream& operator<< (ostream& os, const T& data)

•  Y usar los manipuladores vistos anteriormente

Page 46: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Clase ostream •  El método put permite escribir un carácter en el

stream

ostream& put (char ch)

•  El método write permite escribir n caracteres de un array en el stream

ostream& write (const char* pch, int n)

•  El método flush fuerza el vaciado del buffer asociado al stream

ostream& flush ()

Page 47: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Clase ostream •  El método tellp permite obtener la posición en

el stream de salida (principalmente ficheros)

pos_type tellp ()

•  Los métodos seekp permiten cambiar la posición de escritura en relación a la posición actual…

ostream& seekp (pos_type pos)

• …o en relación a una posición de referencia

ostream& seekp (off_type des, ios_base::seekdir pos)

Page 48: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Clase ostream •  Ejemplos: const char* cadena = “Hola mundo”; cout << cadena << endl; cout.write (cadena, 10); cout.write (“\n”, 1); cout.flush (); for (unsigned i = 0; i < 10; i++) cout.put (cadena[i]);

cout.put (‘\n’); cout.flush ();

Page 49: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Clase istream •  Permite realizar operaciones de lectura con y sin

formato:

•  Sin formato: get, getline, read, ignore, peek, gcount, unget, putback

•  Con formato: operator>>

•  Al igual que la clase ostream, permite gestionar errores y reposicionar el puntero de lectura

Page 50: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Clase istream •  La sobrecarga del operador de extracción

permite realizar lectura con formato

•  Se puede sobrecargar para cualquier tipo

istream& operator>> (istream& is, T& data)

•  Y usar los manipuladores vistos anteriormente (aunque algunos pueden tener sentido únicamente para la clase ostream)

Page 51: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Clase istream •  El método get permite leer un carácter del

stream:

istream& get (char& ch)

•  El método getline permite leer una línea, con una longitud máxima hasta encontrar un delimitador

istream& getline (char* ch, int n, char delim = “\n”)

•  El método read permite leer n caracteres

istream& read (char* ch, int n)

Page 52: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Clase istream •  El método ignore extrae y descarta una cadena

de hasta n caracteres, mientras no encuentre un delimitador dado

istream& ignore (int n = 1, int delim = eof ())

•  El método peek devuelve el siguiente carácter del stream sin extraerlo

int peek () const

Page 53: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Clase istream •  El método gcount devuelve el número de

caracteres leídos en la última extracción sin formato

int gcount () const

•  El método unget devuelve el último carácter extraído al stream

istream& unget ()

•  El método putback devuelve c al stream

istream& putback (char c)

Page 54: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Clase istream •  El método tellg permite obtener la posición en el

stream de entrada (principalmente ficheros)

pos_type tellg ()

•  Los métodos seekg permiten cambiar la posición de lectura en relación a la posición actual…

istream& seekg (pos_type pos)

• …o en relación a una posición de referencia

istream& seekg (off_type des, ios_base::seekdir pos)

Page 55: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Clase istream •  Ejemplos char c, cad [100], cad2[10]; cin >> cad; // Introducimos por teclado “Hola mundo” cin.get(c); // cad = “Hola”, c=‘ ‘ cin.getline (cad, 100, ‘\n’); // cad=“mundo” cin.read (cad2, 10); // Introducimos por teclado // “Hola mundo cruel.Adios”

cout << cin.gcount() << endl; // cad2=“Hola mundo”. Imprime 10 cin.ignore (10, '.'); // Ignora “cruel.” cin.putback('!'); // Inserta ‘!’ en el stream cin >> cad; // cad=“!Adios!”

Page 56: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Clase iostream

•  Clase derivada tanto de istream como de ostream

•  Proporciona acceso de lectura/escritura a streams

•  Presenta los mismos métodos que las clases de las que deriva

Page 57: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Gestión de errores •  Los streams manejan 4 bits de error:

•  eofbit: Se alcanzó el final del fichero en una operación de E/S

•  failbit: El método de E/S falló

•  badbit: Hubo un problema con el stream al realizar la operación

•  goodbit: Ninguno de los anteriores bits está activado

•  Los métodos eof, fail, bad y good devuelven el valor de estos bits

Page 58: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Índice •  Sobrecarga de Funciones

•  Sobrecarga de Operadores

•  Entrada/Salida sobre streams básicos

•  Entrada/Salida sobre streams de fichero

•  Entrada/Salida sobre streams de cadena

Page 59: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

E/S sobre streams de fichero ���

•  Proporcionada por el fichero de cabecera: #include <fstream>

•  Provee de las clases ofstream (salida), ifstream (entrada) y fstream (entrada/salida)

•  Distintos modos para abrir un fichero:

ios::in, ios::out, ios::trunc, ios::app, ios::binary, ios::ate

•  El fichero se puede abrir en el constructor o con el método open

Page 60: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Métodos de apoyo •  El método eof indica si se alcanzó el final del

fichero: bool eof () const

•  El método is_open indica si existe un fichero abierto asociado con el stream bool is_open () const

•  El método close cierra el fichero abierto y lo desliga del stream bool close ()

Page 61: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Clase ofstream •  Clase derivada de ostream especializada en

realizar escrituras sobre ficheros

•  El fichero se puede abrir al construir un objeto de tipo ofstream o con el método open

ofstream (const char* nombre_fichero, ��� ios_base::openmode modo = ios::out | ios::trunc)

void open (const char* nombre_fichero, ��� ios_base::openmode modo = ios::out | ios::trunc)

Page 62: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Clase ofstream •  Ejemplo: ofstream of (”fichero.txt"); of.write ("Hola mundo\n", 11); of << "Adios mundo" << endl; for (char c = 'a'; c <= 'z'; c++) { of.put(c); of << ", "; } of << endl; of.close();

Page 63: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Clase ifstream •  Clase derivada de istream especializada en

realizar lecturas desde ficheros

•  El fichero se puede abrir al construir un objeto de tipo ifstream o con el método open

ifstream (const char* nombre_fichero, ��� ios_base::openmode modo = ios::in)

void open (const char* nombre_fichero, ��� ios_base::openmode modo = ios::in)

Page 64: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Clase ifstream •  Ejemplo: ifstream f (”fichero.txt"); char buffer[100]; f.getline (buffer, 100); cout << buffer << endl; f.ignore(100, '\n'); for (unsigned i = 1; i <= 26; i++) { char c; f >> c; cout << c << endl; f.ignore(2, ',');

}

Page 65: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Clase fstream •  Combina las funcionalidades de ifstream y

ofstream

•  El fichero se puede abrir al construir un objeto de tipo fstream o con el método open

fstream (const char* nombre_fichero, ��� ios_base::openmode modo = ios::in | ios::out)

void open (const char* nombre_fichero, ��� ios_base::openmode modo = ios::in | ios::out)

Page 66: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

E/S usando Registros •  Podemos escribir estructuras de datos complejas

•  Los datos se guardan en formato binario, en lugar de escribirse carácter a carácter

•  Podemos hacerlo con los métodos read y write

•  Requiere una conversión de la estructura en un array de caracteres

•  Uso de reinterpret_cast<char*>()

Page 67: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

E/S usando Registros struct nodo_agenda {���

char nombre[30];���char direccion[40];���long telefono;

}; nodo_agenda persona; cin.getline (30, persona.nombre); cin.getline (40, persona.direccion); cin >> persona.telefono; ofstream ofs (“agenda”); ofs.write (reinterpret_cast<char*>(&persona), sizeof(nodo_agenda)); ofs.close ();

Page 68: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Índice •  Sobrecarga de Funciones

•  Sobrecarga de Operadores

•  Entrada/Salida sobre streams básicos

•  Entrada/Salida sobre streams de fichero

•  Entrada/Salida sobre streams de cadena

Page 69: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

La clase String •  Clase que sirve para trabajar con cadenas de

caracteres

•  También almacena el tamaño de la cadena

•  Gestiona automáticamente la memoria dinámica asociada a la cadena

•  Facilita las operaciones más habituales con cadenas de caracteres

•  Hace falta incluir el siguiente fichero de cabecera: #include <string>

Page 70: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

La clase String •  Cómo construimos un objeto de tipo string:

string cad1; // Construye una cadena vacía string cad2 (cad1); // Constructor de copia char arr[] = “Hola mundo”); string cad3 (arr); // Constructor a partir de un array de char

•  Podemos consultar el tamaño de una cadena: cout << “El tamano de cad1 es: “ << cad1.size() << endl;

•  Podemos acceder carácter a carácter: for (unsigned i = 0; i < cad1.size(); i++) cout << cad1[i];

Page 71: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

La clase String •  Podemos asignar cadenas sin miedo (la memoria

la gestiona la propia clase): string cad1 = “Hola mundo”; string cad2 = “Adios mundo”; cad2 = cad1;

•  Si nos interesa, podemos recuperar el array de caracteres asociado al objeto string

string cad1 = “abcdefgh”; const char* arr1 = cad1.c_str(); // Sí añade ‘\0’ const char* arr2 = cad1.data(); // No añade ‘\0’ char buffer[80]; cad1.copy (buffer, cad1.size(), 0);

Page 72: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

La clase String •  También podemos realizar las operaciones de

comparación habituales: ==, !=, <, >, <= y >=

•  Se comparan letra por letra y se usa el orden alfabético

string str1 = “abcdefg”, str2 = “Abcdefg”; if (str1 < str2) cout << str1 << endl;

else cout << str2 << endl;

Page 73: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

La clase String •  Se pueden insertar caracteres en una cadena: string cad = “Hola”; cad += “ mundo”; // Añade “ mundo” al final cad.append (“ cruel”); // Añade “ cruel” al final cad.insert (11, “nada “); // Inserta “nada “ en la posición 11 cout << cad << endl; // Imprime “Hola mundo nada cruel”;

•  Y concatenar dos cadenas: string cad1 = “Hola”; string cad2 = “ mundo”; string cad3 = cad1 + cad2; cout << cad3 << endl; // Imprime “Hola mundo”

Page 74: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

La clase String •  También podemos buscar subcadenas: int pos; string cad = “abcdefghijk”; pos = cad.find (“efg”); // pos = 4 pos = cad.find (“i”); // pos = 8

•  Reemplazar subcadenas: cad.replace (cad.find (“efg”), 2, “ zyx ”); // cad = “abcd zyx ghijk”

•  Y extraer subcadenas: string cad1 = “Esto es una cadena”; string cad2 = cad1.substr (12, 6); // cad2 = “cadena”

Page 75: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Entrada/Salida sobre streams de cadena

•  Proporcionada por el fichero de cabecera: #include <sstream>

•  Provee de las clases ostringstream (salida), istringstream (entrada) y stringstream (e/s)

•  Permite realizar operaciones de E/S sobre objetos de tipo string (parecido al sprintf de C)

•  Se pueden usar los métodos de las clases básicas istream, ostream y stream (respectivamente)

Page 76: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Entrada/Salida sobre streams de cadena

•  Definen dos métodos adicionales:

string str ( ) const��� void str (const string & s)

•  Permiten recuperar e inicializar la cadena asociada al stream

•  También se les puede asociar una cadena en el constructor

istringstream (const string& str, ��� ios_base::openmode modo = ios_base::in)

Page 77: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Ejemplo con ostringstream ostringstream buffer; string nombre = "Antonio"; int edad = 27; char aficion[] = "leer"; buffer << "Hola. Me llamo " << nombre << ", tengo " << edad << " tacos y me gusta " << aficion << endl;

cout << buffer.str() << endl;

Page 78: Sobrecarga de Operadores y E/S en C++laurel.datsi.fi.upm.es/.../cursos/cplusplus/sobrecarga_y_streams.pdfEntrada/Salida sobre streams de cadena" Visión General de la E/S en C++" •

Ejemplo con istringstream string nombre2; int edad2 = 0; char aficion2[80]; istringstream buffer2 ("Antonio , 27 , leer"); buffer2 >> nombre2; // nombre2 = “Antonio” buffer2.ignore(100, ','); // Descartamos la , buffer2 >> edad2; // edad2 = 27 buffer2.ignore(100, ','); // Descartamos la , buffer2 >> aficion2; // aficion2 = “leer”