PDF de programación - Sobrecarga de Operadores y E/S en C++

<<>>
Imágen de pdf Sobrecarga de Operadores y E/S en C++

Sobrecarga de Operadores y E/S en C++gráfica de visualizaciones

Publicado el 3 de Mayo del 2017
967 visualizaciones desde el 3 de Mayo del 2017
511,5 KB
78 paginas
Sobrecarga de Operadores y

E/S en C++


Antonio LaTorre de la Fuente


Í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


Sobrecarga de Funciones


•  Nuevo con respecto a C

•  Funciones con el mismo nombre pero distinto
•  Útil si se quiere poder realizar una misma

prototipo: número y/o tipo de argumentos


operación sobre distintos tipos de datos


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;


}



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)



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);



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);}



Í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


Operadores en C++


•  Lista de operadores válidos en C++


+

~

++

+=

-

!

--

-=

*

,

<<

*=

/

=

>>

/=

%

<

==

%=

^

>

!=

^=

<<=

>>=

[]

•  Se declaran de la siguiente forma:


()

->

->*

&

<=

&&

&=

|

>=

||

|=

new

delete

tipo operator operador([argumentos])


Operadores en C++

•  Hay algunos operadores especiales que no
pueden ser sobrecargados

• 
• 
• 
•  ?: (operador condicional)

•  sizeof (tamaño de)

•  typeid (identificación del tipo)


. (selección de un miembro)


:: (resolución de ámbito)


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


Precedencia de Operadores

•  Los operadores en C++ tienen distinta
•  Lo mejor es usar () en casa de no estar seguro

•  Tabla de precedencias:


precedencia, y a veces no es obvio


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


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



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


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);


}


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);


}


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);


}



Sobrecarga de operadores

•  Ejemplo: Números Complejos



class Complejo {


public:

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



private:

double real;
double imag;


}


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;


}


Operadores Relacionales

•  Comparación de números complejos:



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



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


}


Operadores de auto-incremento

•  Son operadores unarios

•  Permiten pre-incrementar y post-incrementar el

valor de una variable



Pre-incremento:
Post-incremento:


C C::operator++()


C C::operator++(int x)


Complejo Complejo::operator++() {



real += 1;
return *this;


}


acceder a los elementos privados de esa clase


Funciones “Amigas”

•  Son funciones ajenas a una clase que pueden
•  Ejemplo:

•  Tenemos dos clases: Vector y Matriz

•  Queremos definir el producto vectorial entre
•  El contenido de los objetos es privado


ambas clases


Funciones “Amigas”


class Vector {


class Matriz {


friend operator* (const Matriz&

matriz, const Vector& vector);


friend operator* (const Matriz&

matriz, const Vector& vector);


public:






private:

int size;
int* data;


}


public:






private:

int rows, columns;
int** data;


}


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


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++)



return *this;


data[i] = vector.data[i];

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;


}



Operadores de inserción y extracción

•  Permiten escribir / leer en la salida / entrada
•  Hay que sobrecargar los operadores:


estándar


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



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 << …


}


Operador de Indexación

•  Es el operador []

•  Es un operador binario y de clase: recibe el
•  Útil, p.ej., para acceso seguro a datos:


objeto donde se aplica y el índice facilitado


int Vector::operator[] (int i) {



return data[i];


if (i >= 0 && i < this->size)


else {



}



cout << “Posición incorrecta: “ << i << endl;

return 0;

}


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;


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;



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


Operadores de conversión

•  Se usan para proporcionar una conversión de un
•  Tiene la sintaxis:

•  Donde C es el tipo de usuario que queremos

convertir y T es el tipo en el que queremos
convertir C



C::operator T();


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;


Ambigüedades en la conversión


Surgen si hay varias conversiones implícitas posibles


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.



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
  • Links de descarga
http://lwp-l.com/pdf3304

Comentarios de: Sobrecarga de Operadores y E/S en C++ (0)


No hay comentarios
 

Comentar...

Nombre
Correo (no se visualiza en la web)
Valoración
Comentarios...
CerrarCerrar
CerrarCerrar
Cerrar

Tienes que ser un usuario registrado para poder insertar imágenes, archivos y/o videos.

Puedes registrarte o validarte desde aquí.

Codigo
Negrita
Subrayado
Tachado
Cursiva
Insertar enlace
Imagen externa
Emoticon
Tabular
Centrar
Titulo
Linea
Disminuir
Aumentar
Vista preliminar
sonreir
dientes
lengua
guiño
enfadado
confundido
llorar
avergonzado
sorprendido
triste
sol
estrella
jarra
camara
taza de cafe
email
beso
bombilla
amor
mal
bien
Es necesario revisar y aceptar las políticas de privacidad