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
477 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
Es necesario revisar y aceptar las políticas de privacidad