clases y objetos en c++ · a objetos y, en particular, para especificar argumentos de funciones y...

64
Clases y objetos en C++ Segunda parte

Upload: others

Post on 08-Aug-2020

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Clases y objetos en C++ Segunda parte

Page 2: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Funciones miembros const

Para hacer el puntero this const en

una función miembro, debe declararlo

dentro de la definición de la clase

Dentro de la clase Vagon

int compare(Vagon v) const

{

return this->Volumen()>

v.Volumen();

}

Page 3: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Funciones miembros const

Para especificar que una función miembro es const, se añade la palabra clave const al final de la cabecera de la función

El hacer el puntero this const, significa que no puede figurar ningún dato miembro en el lado izquierdo de una asignación, caso contrario será indicado como un error por el compilador

Una función const no puede invocar una función no const de la misma clase puesto que, podría modificar el objeto con el cual se invoca la función

Page 4: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Funciones miembros const

Cuando una función miembro const se define fuera de la clase, el encabezado de la definición de la función debe añadir la palabra const, tal como se lo hace en el prototipo de dicha función dentro de la clase.

Sino se lo hace, el código no compila. Una función con el modificador const es diferente a una función sin este modificador. Muchas veces es útil tener una versión const y una versión sobrecargada no const

Page 5: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Arrays de objetos

Se puede declarar un array de objetos de

una clase, de la misma forma en que se lo

hace con un array de tipos de datos

primitivos

Cada elemento de un array de objetos

provoca que el constructor por defecto

sea invocado. Importante que la clase

tenga uno (si es que tiene por lo menos

un constructor)

Page 6: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Arrays de objetos

Vagon vagones[5];

Esta declaración implica que se invoque 5 veces

el constructor por defecto (no arg)

Todos los constructores (sobrecargados)

tendrán todos distintos argumentos así que, el

compilador no detectará ninguna ambigüedad

Vagon (){

alto = ancho = longitud = 1.0;

}

Page 7: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Punteros a objetos de una clase

El uso de punteros a objetos es muy

importante en la programación orientada

a objetos y, en particular, para especificar

argumentos de funciones y para retornar

de las mismas, por eficiencia en uso de

memoria y de tiempo insumido en

generar copias de los objetos

Se declara de la misma forma que

cualquier puntero

Page 8: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Punteros a objetos de una clase

Por ejemplo, Vagon *pv=0;

pv=&unVagon;

Como con el puntero this para, invocar

una función miembro o, dentro de una de

la definición de una de ellas, acceder a un

campo, uso el operador ->

cout<<pv->Volumen()<<endl;

Page 9: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Punteros a objetos de una clase

//comparo dos vagones por su volumen

int Vagon::compare (Vagon* pv) const

{

return this->Volumen() > pv- >Volumen();

}

Page 10: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Punteros a objetos de una clase Vagon* pv1=&unVagon; Vagon* pv2=&otroVagon; Vagon vagones[5] … if(pv2->compare(pv1)) cout<<“otroVagon es mayor que unVagon\n”; pv1=vagones; vagones[2]=otroVagon; cout<<“Volumen de vagones[2]= “<<(pv1+2)->Volumen()<<endl;

Page 11: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Referencias en C++

Page 12: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Referencias

Una referencia es un alias de otra variable

y puede utilizarse en lugar del nombre de

la variable de la cual es un alias.

Debido a que no es un puntero, la

variable de la cual es un alias, debe

especificarse cuando se declara la

referencia y, a diferencia de un puntero,

no puede alterarse para representar otra

variable

Page 13: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Referencias

long number=0;

long& rnumber=number;

rnumber+=10; //number=10

Con punteros

long *pnumber=&number;

*pnumber+=10;//desreferencio

Page 14: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Referencias a objetos de una clase

Al igual que con los punteros, no hay

diferencias al declarar y usar una

referencia a objetos de una clase y una a

tipo de datos primitivos

Vagon& rv=unVagon;

cout<<rv.Volumen()<<endl;

Page 15: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Constructor de copia

Page 16: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Constructor de copia

La importancia de las referencias a objetos de una clase, está realmente en el contexto de argumentos y valores de retorno de funciones

El constructor de copia es un constructor que crea un objeto inicializándolo con otro objeto existente de la misma clase

Se podría escribir el prototipo dentro de la definición de una clase, como

Vagon(Vagon v);

Page 17: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Constructor de copia

Si se escribe la declaración

Vagon v2=unVagon; Genera una llamada al constructor de copia

de la siguiente forma Vagon::Vagon(unVagon)

Esto no parece presentar problemas hasta que, se ve que los argumentos se pasan por valor (copia), es decir el compilador tiene que generar una copia de unVagon, para ello llamará al constructor de copia! Y así en forma recursiva, terminando con un número infinito de llamadas al constructor de copia

Page 18: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Constructor de copia

La solución es usar una referencia const como argumento

Vagon (const Vagon& v);

Ahora el argumento del constructor no necesita copiarse, sólo debe inicializarse el argumento tipo referencia con el objeto a copiar.

El calificador const asegura que el argumento no puede modificarse dentro de la función

Page 19: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Constructor de copia

Siempre declare un argumento de tipo referencia como const, a menos que la función deba modificar dicho argumento

Se puede implementar el constructor de copia como Vagon::Vagon(const Vagon& v){ alto=v.alto; ancho=v.alto; longitud=v.longitud; }

Igualmente podría usarse el formato de lista de inicialización para establecer los valores de los campos

Page 20: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Constructor de copia

Page 21: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Constructor de copia

Page 22: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Ejemplo

La salida por pantalla al ejecutar main

Se invoca 2 veces al destructor, delete borra la memoria asignada por new, en este caso, la memoria apuntada por pM; debido a que pM apunta a un objeto CMessage (que tiene definido un destructor), delete además invoca al destructor de esta clase para liberar el espacio en memoria reservada para algunos campos

Page 23: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Constructor de copia

Cuando en una clase se asigna memoria

dinámicamente para algún campo el

constructor de copia por defecto no es

adecuado, por ejemplo

Page 24: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Constructor de copia

El efecto del constructor de copia por

defecto será copiar la dirección

almacenada en el puntero miembro

(pmessage) desde motto1 a motto2,

con lo cual lograremos tener un string

compartido por dos objetos

Page 25: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido
Page 26: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Constructor de copia

Si el string compartido se cambia en uno

de los objetos, también cambiará en el

otro

Si se destruye motto1 (o a la inversa), el

puntero pmessage de motto2 quedará

apuntando a un área de memoria que fue

liberada y, si se utiliza posteriormente,

puede ocurrir un desastre!

Page 27: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Constructor de copia Lo mismo ocurrirá con una función que tome

como argumento un objeto de tipo CMessage.

El argumento es local (paso por valor, se genera

1 copia con el constructor de copia por

defecto) a esta función y cuando se termine de

ejecutar, el destructor se invoca y se borra el

área de memoria apuntada por pmessage (en la

copia y en objeto original este puntero apuntan

al mismo string)

Page 28: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Constructor de copia

En el ejemplo, el puntero pmessage en el objeto que se pasa a la función (thought) aún apunta a un área de memoria que se borró.

La próxima vez que se intente usar dicho objeto (o aún cuando no lo use nunca ya que en algún momento, por ejemplo al terminar de ejecutar main, deberá borrarlo), el programa se puede comportar de formas extrañas

Page 29: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Constructor de copia

Moraleja: Si se asigna memoria

dinámicamente para algún campo de una

clase, implemente un constructor de

copia

Page 30: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Sigamos sobrecargando operadores

Trabajando con el ejemplo original que

trabaja con contenedores(cajas) tipo

prismas rectangulares (libro Ivor

Horton`s Beginning Visual C++ 2008

Page 31: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Sobrecarga de operadores

Page 32: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Soporte completo a la comparación

Con este operador hay cosas que no puedo hacer

El operador sobrecargado, no servirá para esta operación, se producirá un error al compilar, para ello es necesario escribir otra versión del operador >.

Recordar que el argumento que se le pasa corresponde al operando derecho de >, el operando izquierdo será definido implícitamente por el puntero this

Page 33: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Soporte completo a la comparación

El operador resulta

Pero, para una sentencia como,

Se puede pensar que lo resolvería sobrecargando el operador < que, acepte un operando (argumento) derecho de tipo double y reescribir la sentencia del if

Page 34: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Soporte completo a la comparación

Pero, el uso de los objetos debería ser tan natural como posible, no se debería artificialmente restringir las formas en las cuales se usan los objetos en una expresión.

Un operador binario sobrecargado siempre provee el operando izquierdo mediante el puntero this.

Con lo cual tenemos 2 opciones para resolver este problema: usar una función ordinaria o usar una función friend

Page 35: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Soporte completo a la comparación

Debido a que, en el operador no se accede

directamente a los campos privados (se usa

Volume(), declarada public) no se

necesita una función friend, de forma tal

que, se usará una función ordinaria, con lo

cual, el prototipo debe estar fuera de la

definición de la clase (por ejemplo, luego de

la definición de la clase, nunca antes de ella,

salvo que se use una declaración de clase

incompleta antes del prototipo)

Page 36: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido
Page 37: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Sobrecarga del operador de

asignación Sino se lo provee, el compilador suministra

uno por defecto, simplemente hace una copia miembro por miembro, similar a lo que ocurre con el constructor de copia por defecto.

Sin embargo, ambos no deben confundirse. El primero se invoca cuando se encuentra una asignación (no inicialización) donde ambos operandos del = son objetos del mismo tipo

Para la clase CBox este operador de asignación por defecto funciona sin problemas

Page 38: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Sobrecarga del operador de

asignación Pero, para el caso de clases con campos

que asignan memoria dinámicamente, al

igual que con el constructor de copia,

este operador de = puede traer

problemas.

Volviendo a la clase CMessage, si se usa

el operador de asignación por defecto

Page 39: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Sobrecarga del operador de

asignación El efecto es esencialmente el mismo que

para el constructor de copia por defecto, nuevamente tenemos un puntero pmessage al mismo string

Se necesita crear un operador de asignación, que copie el texto apuntado por pmessage del objeto que se pasa como argumento, al área de memoria propiedad del objeto que está del lado izquierdo

Page 40: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Sobrecarga del operador de

asignación

Page 41: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Sobrecarga del operador de

asignación La operación de asignación es muy simple

pero, hay algunas sutilezas que necesitan

investigarse.

El operador retorna una referencia, para

visualizar el motivo: es probable que el

resultado de la asignación, a su vez,

necesite usarse en el lado derecho de

otra asignación

Page 42: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Sobrecarga del operador de

asignación Debido a que, el operador asignación es

asociativo por derecha, la operación se realiza en este orden (primero se asigna motto2=motto3)

La llamada al operator=() que está entre paréntesis, debe retornar un objeto de tipo CMessage que, pueda usarse como argumento del otro operator=(), con lo cual, el tipo de retorno podría ser de tipo CMessage o CMessage&,con lo cual en este caso no es obligatorio retornar una referencia

Page 43: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Sobrecarga del operador de

asignación Sin embargo, considere el siguiente

ejemplo, donde se usan ( ), para forzar

que la asignación dentro de ellos se

realice primero:

Esto se traslada a

Page 44: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Sobrecarga del operador de

asignación Ahora se tiene una situación donde, el objeto

retornado por el operator=() (motto1=motto2) se usa del lado izquierdo del otro operator=(),

si elijo usar como tipo de retorno del operador de asignación a CMessage (en lugar de una referencia), esto no es legal debido a que se generará una copia temporal del objeto retornado y, el compilador no permitirá que use esta copia temporal (no es un lvalue) para invocar una función miembro (en este caso operator=).

Page 45: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Sobrecarga del operador de

asignación La única forma en que el código compile es

retornar una CMessage& (es un lvalue),

único tipo posible de retorno para permitir

un uso completamente flexible del operador

de asignación

Aquí se ve la utilidad del puntero this ya

que, se necesita devolver una referencia al

objeto apuntado por this (objeto con el

cual se invoca al operador, operando

izquierdo de =), por eso se retorna *this

Page 46: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Sobrecarga del operador de

asignación La 2º sutileza a tener en cuenta es que, cada

objeto ya tiene asignada memoria dinámicamente para alojar un string, de forma tal que,

lo 1º que se hace en un operador de asignación en estos casos, es borrar el espacio de memoria reservado para el 1º objeto (lado izquierdo del =) y, reasignar suficiente memoria para alojar el string perteneciente al 2º objeto (lado derecho del =).

Una vez hecho esto, el string del objeto a copiar, se copia al nuevo espacio de memoria ahora propiedad del objeto que está del lado izquierdo de la asignación (apuntado por this)

Page 47: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Sobrecarga del operador de

asignación Pero, hay un defecto en esta

implementación del operador =

¿Qué ocurre si se tiene algo como esto?

Muy probablemente el intento de auto

asignación quede enmascarado detrás de

un puntero que apunte a motto1

Page 48: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Sobrecarga del operador de

asignación En este caso, el operador = borra la

memoria asignada al string contenido en motto1, e intenta reservar memoria basada en la longitud de dicho string que se borró y copiar la vieja memoria asignada (ya no existe) que puede estar corrompida

Para evitar esto, simplemente, al principio del operador de asignación se chequea que sean distintos los 2 operandos de =

Page 49: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Sobrecarga del operador de

asignación

Page 50: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Sobrecarga de operador de

asignación Moraleja: Implemente el operador de

asignación siempre que la clase tenga

campos que reserven memoria

dinámicamente

Page 51: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Sobrecarga del operador suma

En el caso de la clase CBox la suma debe retornar un nuevo objeto CBox que será la suma, sea lo que sea que signifique, de los 2 operandos (2 objetos de tipo CBox).

¿Qué significará sumar 2 objetos de esta clase? En este ejemplo se consideró que la suma devolverá un objeto CBox que sea capaz de contener lo mismo que los dos contenedores sumados, uno encima del otro

Page 52: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Sobrecarga del operador suma

Page 53: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Sobrecarga del operador suma

En la declaración del operador suma, hay que suministrarle los dos operandos

Se pasa como argumento una referencia para evitar la copia innecesaria del operando derecho de la suma y,

se declara const a dicha referencia para indicar que la función no modificará el argumento y que, se permitirá tener un operando derecho que sea const,

también se declara const al operador ya que no modificará el objeto con el cual se lo invocará (operando izquierdo de la suma)

Page 54: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Sobrecarga del operador suma

Page 55: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Sobrecarga del operador suma

Se construye un objeto local a

partir del objeto con el cual se invoca, el

operando izquierdo de la suma (*this) y

el objeto que se pasa como argumento

(operando derecho de la suma), aBox.

Recuerde que así como está definida la

función, retorna una copia temporal del

objeto local creado. El objeto local se

descarta cuando la función retorna

Page 56: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Sobrecarga del operador suma

Se modifica el constructor para

asegurarse que el valor del campo que

almacena la longitud del contenedor no

sea menor (pueden ser iguales) que el

valor del campo que contiene el ancho

del mismo

Page 57: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Sobrecarga del operador suma

Se añade además una función para

mostrar las dimensiones de un objeto

Cbox; con la misma se podrá verificar que,

la versión sobrecargada del operador

suma funciona correctamente

Si sumamos, por ejemplo 3 objetos, el

operador se llamará 2 veces

Page 58: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Sobrecarga del operador suma

La salida por pantalla será:

Page 59: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Sobrecarga del operador suma

También podría haberse definido el

operador suma usando una función

friend y se usará el operador . para

acceder a los campos de los dos objetos

pasados como argumentos.

Page 60: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Sobrecarga de los operadores ++ y

-- Estos operadores tienen algunas

características que los distinguen de los

otros

Ambos operadores tienen dos formas:

prefija y postfija y, el efecto es diferente

según se use una forma u otra

Utilizaremos una clase muy simple con un

campo double que representa una

longitud

Page 61: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Sobrecarga de los operadores ++ y

-- Para poder diferenciar las 2 versiones del

mismo operador, se lo hace usando

distintos argumentos.

La forma prefija no toma argumentos y, la

forma postfija, toma un argumento de tipo

int que, no se usa en la implementación,

sólo sirve para distinguir las 2 versiones

Page 62: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Versión prefija

En esta versión el operando se

incrementa o decrementa en 1, antes de

que su valor se use en una expresión,

retornando una referencia al objeto actual

(con el cual se invoca, único operando)

luego de incrementarlo o decrementarlo

Page 63: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Versión postfija En esta versión, el único operando es

incrementado o decrementado en 1,luego que el mismo es usado en una expresión. Esto se logra creando un nuevo objeto, copia del objeto original pasado como argumento, antes de proceder a incrementar el objeto actual, retornando la copia del objeto original sin incrementar, después de modificar el objeto actual

Declarar el valor de retorno como const previene que expresiones como data++++ compilen

Page 64: Clases y objetos en C++ · a objetos y, en particular, para especificar argumentos de funciones y para retornar de las mismas, por eficiencia en uso de memoria y de tiempo insumido

Sobrecarga de los operadores ++ y

--