Sie sind auf Seite 1von 43

Informtica II

Clase 8: Sobrecarga

CONTENIDO

Sobrecarga de Funciones

Constructores Copia

Sobrecarga de operadores

Sobrecarga de operadores

SOBRECARGADO DE FUNCIONES
Consiste en crear diferentes funciones
con el mismo nombre, con el fin de
ofrecer al usuario una manera ms
sencilla de recordar las funciones.
//Algunos protototipos

int funcion(int);
int funcion(long, long);
int funcion(long);

SOBRECARGADO DE FUNCIONES
Cuando se realiza la invocacin de una
funcin sobrecargada, el compilador
decide cual de ellas se utilizar mediante
un proceso denominado resolucin de
sobrecarga ("Overload resolution").
Se resuelve aplicando ciertas reglas para
verificar cual de las declaraciones se
ajusta mejor al nmero y tipo de los
argumentos utilizados.
4

SOBRECARGADO DE FUNCIONES
El proceso sigue unas reglas en el orden
precedencia sealado:
Concordancia exacta en nmero y tipo.
Concordancia
promociones
de
los
asimilables.

tipos

Ejemplo:char,short,bool,aint.

Concordancia de conversiones estndar.


Ejemplo:intadouble;clase-derivadaaclase-padre.

Concordancia de conversiones definidas por el


usuario.
Concordancia usando la elipsis (...) en funciones
con nmero variable de parmetros.
5

SOBRECARGADO DE LOS
MTODOS DE LAS CLASES
Los mtodos de las clases tambin pueden ser
sobrecargados como el resto de las funciones,
su sintaxis es prcticamente igual.
class Rectangulo
{
public:
// funcin DibujarFigura sobrecargada de la clase
void
DibujarFigura() const;
void DibujarFigura()
const;
void
DibujarFigura(int unAncho,
void DibujarFigura(int
unAncho, int
int unaAltura)
unaAltura) const;
const;
private:
int suAncho;
int suAltura;
};
6

SOBRECARGADO DE LOS
MTODOS DE LAS CLASES
Los constructores, al ser mtodos
especiales de las clases tambin pueden
ser sobrecargados, y la manera de
hacerlo es igual que el resto de los
mtodos.
OJO!, los destructores no pueden ser
sobrecargados, Porque?

EJEMPLO SOBRECARGA
class carro{
private:
int gGas;
char *marca;
int velMax;
int vel;
bool start;
public:

void carro::acelerar(){
carro::carro(){
gGas=0;
if(--gGas<=0){
marca=0;
vel=0;
velMax=0;
}
vel=0;
else{
start=false;
vel++;
} }
}

carro();
carro(int _gGas,char *_marca="mazda",\
int _velMax=80);
void arrancar();
carro::carro(int
void
carro::acelerar(int
_gGas,char
increment){
*_marca, int
void acelerar();
_velMax){
if(--gGas<=0){
void acelerar(int increment);
gGas=_gGas;
vel=0;
void frenar();
marca=_marca;
}
int getVel() const;
velMax=_velMax;
else{
~carro();
vel=0;
vel+=increment;
};
} }
}

VALORES POR DEFECTO


En el cdigo anterior tenemos que uno de los
constructores tiene argumentos de entrada
planteados por defecto
carro(int _gGas,char *_marca="mazda", int _velMax=80);

carro Deportivo(10,"Renault");

Aqu no asignamos el ltimo


parmetro (int _velMax) al
constructor, este es asignado
por defecto como 80.

VALORES POR DEFECTO


No es posible en la llamada de este constructor
en particular, por ejemplo asignar un valor al
tercer argumento si no ha sido asignado antes
el valor del segundo argumento por defecto.
carro Deportivo(10, ,50);

//no tiene sentido

En cualquier funcin, o mtodo de una clase es


posible instaurar los argumentos por defecto.

10

VALORES DE RETORNO
Con el fin de que el mecanismo de
sobrecarga
sea
independiente
del
contexto, los valores devueltos por las
funciones NO son tenidos en cuenta a
efectos del mecanismo de sobrecarga.
int func (int, char);
int func (float, char);
void func (int, char);

11

CONTENIDO

Sobrecarga de Funciones

Constructores Copia

Sobrecarga de operadores

Sobrecarga de operadores

12

CONSTRUCTORES COPIA
Adicionalmente de ser asignado por defecto un
constructor y un destructor cuando no son declarados
explcitamente en la declaracin de la clase, el
compilador provee un constructor de copia, que es
llamado cada vez que se requiere una copia de un
objeto.
#include <iostream>
using namespace std;
carro Deportivo(10,"BMW",50);
//carro carreras=Deportivo;
carro carreras(Deportivo); //constructor copia por
defecto
int main()
{
50
cout<<Deportivo.getVelMax()<<endl;
50
cout<<carreras.getVelMax()<<endl;
return 0;
}

13

CONSTRUCTORES COPIA
Cada vez que se crea una copia de un
objeto "El constructor de copia es
ejecutado.
Por defecto, el constructor de copia
simplemente copia cada miembro de una
objeto hacia el nuevo objeto. Esta copia
se denomina Copia Superficial.
//Declaracin del constructor de copia
Nombre (tipo variable);
Constructor (const Clase &Objeto); // constructor de copia
14

CONSTRUCTORES COPIA
//Declaracin del constructor de copia
Rectangulo (const Rectangulo &refR);

15

CONSTRUCTORES COPIA
La copia superficial es buena para casi todo tipo
de variables; sin embargo, es muy fcil de romper
cuando los miembros son punteros a objetos en el
Heap.

16

CONSTRUCTORES COPIA
La solucin para evitar problemas ocasionados
por las copias superficiales, es usando los
constructores de copia para que estos hagan la
copia en diferentes espacios del Heap,
realizando lo que se denomina como Copia
Profunda.

17

CONSTRUCTORES COPIA

Cuando se pasa un objeto como argumento a una


funcin o esta lo retorna, se hace una copia
temporal de cada una de sus variables miembro.

Todo constructor de copia, toma como parmetro


una referencia a un objeto de su misma clase.

carro(carro &deportivo);

18

CONSTRUCTORES COPIA

El objetivo del constructor de copia, es crear una copia exacta de


cada variable miembro del objeto pasado como referencia (original).
Este copia se denomina superficial.

Los constructores de copia superficiales funciona perfectamente


cuando se trata de un objeto cuyas variables miembro no son
punteros referenciados a variables u objetos alojados en el Heap
(free store).

En algunas ocasiones se hace necesario definir personalmente un


constructor de copia, que evite que se haga una copia errnea,
donde se garantice la independencia de cada objeto con respecto a
cada una de sus variables miembro (copia profunda).
19

EJEMPLO CLASE COPIA


//El
Declaracin
otro constructor
de//constructor
los otros mtodos
por defecto
#include
<iostream> //
class carro{
//inicializacin
carro::getVelMax()
//incializacion
en la const{
etapa de inicializacin
en la etapa de
using
namespace
std; int
private
:
inicializacin
return velMax;_gGas,char
*_marca, int _velMax):
char
"BMW; carro::carro(int
intmarca[]=
*gGas;
carro::carro():gGas(0),marca(0),velMax(0),\
velMax(_velMax){
} marca(_marca),
carro
charDeportivo(10,marca,50);
*marca;
gGas=new int;
vel(0), start(false){
const
int
velMax;
carro carreras(Deportivo);
//carro carreras=Deportivo;
*gGas=_gGas;
gGas=new int;
carro::~carro(){
//Destructor
int vel;
bool start;

delete gGas; }
gGas=0; //NULL

int main()
public:
}
{
carro();
cout<<Deportivo.getVelMax()<<endl; 50
carro(int _gGas,char *_marca,int
cout<<carreras.getVelMax()<<endl;
_velMax);
50
return
0; el constructor de copia.
//se declara
} carro(carro &original); //la variable constante debe ser inicializada en la

etapa de inicializacin igualmente en el constructor


void arrancar();
de copia.
void acelerar();
//constructor de copia
void acelerar(int increment);
carro::carro(carro
void frenar();
&original):velMax(original.getVelMax()){
int getVel() const;
//se hace una copia de cada una de las variables
int getVelMax() const;
miembro
int getgGas() const;
marca=original.marca;
void setVelMax(int vel);
vel=original.vel;
~carro();
start=original.start;
};
gGas=new int;
20

CONTENIDO

Sobrecarga de Funciones

Constructores Copia

Sobrecarga de operadores

Sobrecarga de operadores

21

SOBRECARGADO DE LOS
OPERADORES
La sobrecarga de operadores quiere decir que
se pueden redefinir algunos de los operadores
existentes en C++ para que acten de una
determinada
manera,
definida
por
el
programador, con los objetos de una clase
creada por el mismo.

La sobrecarga de operadores se emplea


para declarar como es que funciona dicho
operador cuando se utilizan sobre los
objetos.
22

FUNCION OPERADOR
Existen dos clases de sobrecargas:
De un operador
De dos operadores

Cuando en C++ determinamos el uso de


un operador : (+, -, *, /, %, =, <, )
estamos haciendo uso de funciones con
identificadores (nombres) especiales.

23

FUNCION OPERADOR
Cuando
sobrecargamos
cualquier
operador nos referimos a cambiar su
funcionalidad pero
no
su
gramtica original.
As por ejemplo:
Suma: a + b; a+;
Asignacin: a = a+b; a + b = a;

24

SOBRECARGA DE
OPERADORES

La sobrecarga de un operador puede ser


declarada de la siguiente forma:
tipodeRetorno operator op (parametros);
Void, int,
char,

Palabra
reservada

-, --, + , ++,
=, ==,

Void, int,
char,

void operator ++ ();


void operator ++ ();
// Ejemplo de una declaracin para el sobrecargado del
// Ejemplo de una declaracin para el sobrecargado del
operador ++
operador ++
25

FUNCION OPERADOR
As, cuando hacemos la sobrecarga de un
operador y realizamos su llamado nos
referimos a:
Expresin

Mtodo

Funcin

@a

a.operator@()

operator@(a)

a@b

a.operator@(b)

operator@(a,b)

a=b

a.operator=(b)

a[b]

a.operator[](b)

a->

a.operator->()

a@

a.operator@(0)

operator@(a,0)

26

FUNCION OPERADOR
Suponiendo que tenemos tres objetos de
una misma clase: c1, c2, c3
c3 = c1.suma(c2);

Sera ms sencillo utilizar la sobrecarga


de operadores:
c3 = c1.operator+(c2);
c3 = c1+ c2;

27

SOBRECARGA DE
OPERADORES
El objetivo de la sobrecarga de operadores
es simplificar al mximo el cdigo a
escribir.
A cambio agregar algunas definiciones en
las clases.
Una clase que disponga de operadores
sobrecargados es una clase ms compleja
de definir, pero ms sencilla e intuitiva de
utilizar.
28

EJEMPLO SOBRECARGA DEL OPERADOR


PREFIJO
using namespace std;
contador mycontador();

void contador::setvariable(int
contador::contador():
variable(0){}
_variable){
variable=_variable;
//constructor de copia
}
int main()
class
contador{
contador::contador(contador& original){
{
private:
voidvariable=original.variable;
contador::incrementar(){
int
mycontador.incrementar();
variable;
} variable+=2;
cout<<"incremento utlizando un metodo:
} " \
2
public:
<< mycontador.getvariable()<<endl;
int contador::getvariable() const{
contador();
++mycontador;
return variable;
4
//constructor
cout<<"incremento
de copia
sobrecargando el operador
}
++:" \
contador(contador&
<<mycontador.getvariable()<<endl;
original);
int getvariable() const;
return
0;
void
setvariable(int
_variable);
} void incrementar();
//definicin de la sobrecarga del operador
//sobrecarga el operador
preincremento (++i)
//preincremento (++i)
void contador::operator++(){
void operator++();
variable+=2;
~contador();
}
};
//Destructor
contador::~contador(){}
29

EJEMPLO SOBRECARGA DEL OPERADOR


PREFIJO
Ahora lo que generalmente se desea es poder es
retornar un objeto tipo contador, de este modo
poder reasignarlo a otro objeto tipo contador.

using
//definicin
namespace std;
de la operador
preincremento
(++i)
contador
cont1;
contador::operator++
int contador
main()
(){
{
variable+=2;
cont1.incrementar();
contador temp;
cout<<"cont1:
" <<cont1.getvariable()<<endl;
temp.setvariable(variable);
contador
cont2=++cont1;
return temp;
cout<<"cont2:
"<<cont2.getvariable()<<endl;
}

cont1: 2
cont2: 4

return 0;
}

30

EJEMPLO SOBRECARGA DEL OPERADOR


PREFIJO
Pero por qu crear un objeto temporal?, recordemos que
cada objeto temporal debe ser construido, destruido, y
copiado luego del retorno del mtodo, siendo cada
operacin de estas muy costosa computacionalmente
hablando.
El objeto cont1 ya existe y posee un valor adecuado para
variable, porque no retonarlo a s mismo mediante el
puntero this (*this es el objeto, mientras que this es su
direccin)
//definicin de la operador preincremento (++i)
const contador& contador::operator++(){
++variable;
return *this;
}

31

EJEMPLO SOBRECARGA DEL OPERADOR


PREFIJO

ta lnea de cdigo se presenta los siguientes p


contador cont2=++cont1;

Es llamado a travs del objeto cont1, el mtodo que


sobrecarga el operador preincremento (++).

Dicho mtodo incrementa la variable, y se retorna a s


mismo como referencia (contador&) .

Es llamado el constructor de copia del objeto cont2, el


cual recibe como argumento por defecto la referencia de
un objeto del mismo tipo (cont1).
32

SOBRECARGADO DEL OPERADOR


POSFIJO
Los operadores posfijos son los que
primero devuelven el valor y luego opera
la variable, ejemplo: i++;
Para sobrecargar el operador posfijo en
los objetos, es necesario el uso de objetos
temporales dentro de los mtodos para
luego devolverlos por valor.

33

SOBRECARGADO DEL OPERADOR


POSFIJO
Declaracin
const Contador Contador::operator++(int flag)
{
Contador temp(*this);
variable+=2;
return temp;

flag tipo int tiene valor 0 y no se


flag tipo
int solo
tienesirve
valor como
0 y no se
utiliza
nunca,
utilizade
nunca,
solo sirve
criterio
distincin
frentecomo
al
criterio de
frente al
operador
dedistincin
preincremento.
operador de preincremento.

}
/* Notese el uso de la variable flag... dicha vble
es declarada pero nunca es utilizada!! */
34

SOBRECARGA DEL OPERADOR DE


POSTINCREMENTO

Creamos un objeto temporal


copia del objeto original.

Modificamos el valor de la
variable del objeto original.

Retornamos el objeto copia


temporal.

De este modo, el valor del objeto ser modificado, pero en la


De este modo, el valor del objeto ser modificado, pero en la
expresin donde aparezca se tomar el valor antes de modificar.
expresin donde aparezca se tomar el valor antes de modificar.

35

EJEMPLO SOBRECARGA DEL OPERADOR


POSFIJO
using namespace std;
//Constructor
int
contador::getvariable() const{
contador::contador():variable(0){}
return variable;
cont1: 2
}
cont1: 4
//constructor de copia
contador::contador(contador&
void
contador::setvariable(int
original){
_variable){
cont2: 4
variable=original.variable;
variable=_variable;
cont2: 4
}

class contador{
private:
contador cont1;
//Ejemplo
int variable;
operador posincremento
int main()
public:
cont1: 6
{ contador();
//constructor
cont1.incrementar();
de copia
void contador::incrementar(){
contador(contador&
cout<<"incremento original);
utlizando un//definicion
metodo:
variable+=2;
"<< de
cont1.getvariable()<<endl;
la operador preincremento (++i)
int
contador
getvariable()
cont2=++cont1;
const;
} contador& contador::operator++(){
const
void
cout<<"El
setvariable(int
valor de cont1
_variable);
luego de preincremento
variable+=2;
"<<cont1.getvariable()<<endl;
void
incrementar();
return *this;
cout<<"El valor
de cont2:
"<<cont2.getvariable()<<endl;
//sobrecarga
el operador
preincremento
(+
}
cont2=cont1++;
+i)
const
cout<<"El
contador&
valoroperator
de cont2:
++();
"<<cont2.getvariable()<<endl;
//sobrecarga
cout<<"El valor
del operador
de cont1 posincremento
luego//definicion
de posincremento:
del operador posincremento (i++)
(i++)
"<<cont1.getvariable()<<endl; const contador contador::operator++(int
const contador operator ++(int flag);
flag){
~contador();
return 0;
//hace una copia del objeto
};}

contador temp(*this);
variable+=2;
return temp;

36

SOBRECARGA DE
OPERADORES
1

Un operador puede estar sobrecargado o redefinido varias veces, de


tal manera que acte de un modo distinto dependiendo del tipo de
objetos que tenga como argumentos de entrada.

Las ventajas de la sobrecarga de operadores terminan cuando se


utiliza de modo que aade complejidad o confusin a los programas.
Por ejemplo: no se deber nunca utilizar el operador (-) para
multiplicar matrices o el (+) para imprimir vectores.
Los nicos operadores de C++ que no se pueden sobrecargar son:
El operador punto (.),
El if aritmtico (?:)
El operador sizeof,
El scope operator (::)
puntero a miembro de un objeto (.*).

37

OPERADORES BINARIOS
Son aquellos que requieren
dos
operandos, como la suma o la resta.
Cuando se sobrecargan operadores en el
interior se asume que el primer operando
es el propio objeto de la clase donde se
define el operador. Debido a esto, slo se
necesita especificar un operando como
argumento.

38

SOBRECARGANDO EL
OPERADOR +

using namespace std;

contador::contador():variable(0){}
int
contador::getvariable() const{
cont1: 5
return variable;
contador::contador(int
}
cont2:_variable):
6
variable(_variable){}
cont3: 11
void contador::setvariable(int _variable){
//constructor
variable=_variable;
de copia
contador::contador(contador& original){
}
variable=original.variable;
"<<cont1.getvariable()<<endl;
}
void
contador::incrementar(){
"<<cont2.getvariable()<<endl;
variable+=2;
"<<cont3.getvariable()<<endl;
}

class
contador{
//Ejemplo
operador +
private:
int main()
{ int variable;
public:
contador cont1(5),cont2(6);
contador();
contador cont3=cont1+cont2;
contador(int
_variable);
cout<<"el valor
de cont1 es:
//constructor
de de
copia
cout<<"el valor
cont2 es:
contador(contador&
cout<<"el valor de original);
cont3 es:
int getvariable() const;
void
setvariable(int
_variable);
return
0;
} void incrementar();
//sobrecarga el operador +
contador operator+(const contador&
//definicin del operador +
other);
contador contador::operator+(const contador&
~contador();
other){
};
contador temp;

temp.setvariable(variable+other.getvariable())
;
return temp;
}
39

SOBRECARGANDO EL
OPERADOR =

int main()
{
contador cont1(5),cont2(6);
cont2=cont1;
cout<<"el valor de cont1 es: "<<cont1.getvariable()<<endl;
cout<<"el valor de cont2 es: "<<cont2.getvariable()<<endl;
return 0;
}

Qu pasa si el objeto cont1 tiene como variables


miembro punteros que acceden a memoria dinmica?
El objeto cont2 al ser de la misma clase que cont1
igualmente ya cuenta con espacio en memoria dinmica,
luego solo basta con copiar el nuevo valor respectivo en
dicho espacio.
40

SOBRECARGANDO EL
OPERADOR =
//sobrecarga el operador =
const contador& operator =(const contador& other);
//definicion del operador =
const contador& contador::operator =(const contador&
other){
if(this==&other){
return *this;
}
else{
variable=other.variable;
}
return *this;
}

41

BIBLIOGRAFA
Curso C++ con clase
http://c.conclase.net/curso/?cap=043
Pagina de Referencia lenguaje C++:
http://www.cplusplus.com/reference/std/ex
ception/exception/
http://www.cplusplus.com/reference/std/st
dexcept/
Sams Teach yourselft C++ in 21 days:
http://newdata.box.sk/bx/c/htm/ch20.htm#
Heading1
42

Fin de la clase!

43

Das könnte Ihnen auch gefallen