Documento 89543

Anuncio
Departamento de Informática
Lenguajes de Programación
Universidad Técnica Federico Santa María
Departamento de Informática
Lenguajes de Programación
Universidad Técnica Federico Santa María
Sobrecarga de Operadores
• El usuario puede darle nuevos significados
a operadores existentes en el lenguaje
• Los tipos de operadores son:
3.5 Sobrecarga de Operadores
en C++
– Arímeticos, lógicos y relacionales
– Llamada a función ()
– Subíndice []
– Desreferenciación
– Asignación e inicialiazación
1
III-2
Departamento de Informática
Departamento de Informática
Lenguajes de Programación
Universidad Técnica Federico Santa María
Ejemplo Sencillo
Operadores que se Sobrecargan
class complejo {
double re, im ;
public:
complejo(double r, double i) {re=r; i m=i;}
friend complejo operator+ (complejo, complejo);
friend complejo operator* (complejo, complejo);
// …
};
void f()
{
complejo a(3.4, 2.6);
complejo b(4.5, 2.7);
complejo c(1.0, 1.0);
a = b + c;
Lenguajes de Programación
Universidad Técnica Federico Santa María
+
-
*
/
%
^
&
|
~
!
=
<
>
+=
-=
*=
/=
%=
^=
&=
|=
<<
>>
>>=
<<=
==
!=
<=
>=
&&
||
++
--
->*
,
->
[]
()
new
delete
// equivale a: a = operator (b, c)
}
III-3
Departamento de Informática
Universidad Técnica Federico Santa María
III-4
Departamento de Informática
Lenguajes de Programación
Universidad Técnica Federico Santa María
Operadores Binarios
Operadores Unarios
• Para el operador binario @, a@b puede
interpretarse como:
• Para el operador unario prefijo @, @a puede
interpretarse como:
a.operator@ ()
operator@ (a)
a.operator@ (b)
operator@ (a, b)
Lenguajes de Programación
// función miembro
// función global
// función miembro
// función global
• Para el operador unario posfijo @, a@ puede
interpretarse como:
a.operator@ (int) // función miembro
operator@ (a, int) // función global
• Sintaxis determina operadores unarios aceptados
III-5
III-6
Departamento de Informática
Departamento de Informática
Lenguajes de Programación
Universidad Técnica Federico Santa María
Universidad Técnica Federico Santa María
Ejemplo
class X
// operan con implícitamente con ´this´
X* operator& ();
// & prefijo unario (dirección)
X operator & (X)
// & binario ( and)
X operator ++ (int ); // incremento postfijo
X operator & (X, X); // ERROR: no permite ternario
X operator / ();
// ERROR: unario / no existe
};
// funciones globales (gralmente son amigas de alguna clase)
X
X
X
X
X
X
operator- (X);
operator- (X, X)
operator-- (X&, int );
operator- ();
operator- (X, X, X);
operator% (X);
//
//
//
//
//
//
- prefijo unario
- binario
decremento postfijo
ERROR: sin operandos
ERROR: no permite ternario
ERROR: unario % no existe
Lenguajes de Programación
Observaciones al Significado de
Operadores Sobrecargados
• No es posible inferir significados especiales al
sobrecargar operadores
– e.g.: a += b no permite inferir a =
a+b
• Operadores de asignación =, dirección & y
secuenciación “,” tienen significados especiales al
aplicarlos a clases
• Un función operador debe ser miembro o tomar
como primer argumento un objeto de una clase
declarada
III-7
Departamento de Informática
Universidad Técnica Federico Santa María
III-8
Departamento de Informática
Lenguajes de Programación
Universidad Técnica Federico Santa María
Objetos Grandes (1/2)
Lenguajes de Programación
Objetos Grandes (2/2)
class matriz {
double m[MAX][MAX];
public:
matriz();
matriz operador+ (const matriz&);
// …
};
class matriz {
double m[MAX][MAX];
public:
matriz();
matriz& operador+ (const matriz&);
// …
};
matriz matriz::operator+ ( const matriz& a)
{
matriz suma;
for ( int i =O; i<MAX; i++)
for ( int j =O; j<MAX; j++)
suma.m[i][j] = m[i][j] + a.m[i][j];
return suma;
}
matriz& matriz:: operator + (const matriz& a)
{
matriz suma;
for ( int i =O; i<MAX; i++)
for ( int j =O; j<MAX; j++)
suma.m[i][j] = m[i][j] + a.m[i][j];
return suma;
}
¡Implica copiar suma en el retorno!
¡Más eficiente, pero retorna referencia al stack!
III-9
Departamento de Informática
Universidad Técnica Federico Santa María
III-10
Departamento de Informática
Lenguajes de Programación
Universidad Técnica Federico Santa María
Problema de Asignación
Lenguajes de Programación
Sobrecarga de la Asignación
class string {
char* p;
int
size ;
public:
string(int s) { p = new char[size=s};}
string& operator= (const string&); // asignación
~string() { delete[] p; }
};
class string {
char* p;
int
size;
public:
string(int s) { p = new char[size=s};}
~string() { delete[] p; }
};
void f()
{
string s1(10);
string s2(20);
s1 = s2;
// oops … se genera basura
}
// oops… se destruye dos veces el mismo string
¡Una asignación no declarada produce copia al bit de los objetos!
(como sucede con estructuras)
III-11
string& string :: operator = (const& s)
{
if (this != &s) {
// atención con s=s
delete [] p;
p = new char[size = s .size ];
strcpy (p, s.p);
}
return * this;
}
III-12
Departamento de Informática
Departamento de Informática
Lenguajes de Programación
Universidad Técnica Federico Santa María
Universidad Técnica Federico Santa María
Problema con Inicialización
Constructor de Inicialización
• Para un tipo X, el constructor X(const X&)
realiza inicialización con objeto del mismo tipo
// usando última versión de string
void f()
{
string s1(10);
string s2 = s1;
...
}
Lenguajes de Programación
class string {
char* p;
int
size;
public:
string(int s) { p = new char[size=s};}
string(const string&);
// inicialización
string& operator= (const string&); // asignación
~string() { delete[] p; }
};
// oops .. = es inicialización
// ∴ NO llama a la asignación
// oops … destruye dos veces el mismo string
¡Una inicialización no declarada produce copia al bit de los objetos!
(como sucede con estructuras)
string::string(const string& s)
{
p= new char[size=s.size];
strcpy(p, s.p);
}
III-13
Departamento de Informática
Universidad Técnica Federico Santa María
III-14
Departamento de Informática
Lenguajes de Programación
Universidad Técnica Federico Santa María
Lenguajes de Programación
Ejemplo: Operador [](1/4)
Operador de Subíndice
• El operador [] puede ser sobrecargado
• El tipo de dato que se use en el subíndice
puede ser de cualquier tipo (no necesariamente entero)
• Una aplicación interesante es para definir
arreglos asociativos (acceso por contenido)
class asoc {
struct par {
char* nombre;
int
valor;
};
par*
ar;
// arreglo asociativo
int
max;
// tamaño máximo del arreglo
int
libre;
// posición de primero libre
asoc (const asoc&);
// impide copia de inic.
asoc& operator= (const asoc&);// impide copia de asig.
public:
asoc (int);
int& operator[] (const char*);
void imprimir();
~asoc ();
};
III-15
Departamento de Informática
Universidad Técnica Federico Santa María
III-16
Departamento de Informática
Lenguajes de Programación
Universidad Técnica Federico Santa María
Lenguajes de Programación
Ejemplo: Operador [] (3/4)
Ejemplo: Operador [] (2/4)
int& asoc::operator[] (const char* s)
{
register
par* pp;
// constructor
for (pp=&ar[libre-1]; ar <= pp; pp--)
if(strcmp(s, pp->nombre) == 0)
return pp->valor;
asoc::asoc (int i)
{
max = (i<16) ? 16 : i;
libre = 0;
ar = new par[max];
}
// no se encontró en el arreglo
if (libre == max) {
// arreglo agotado
par* vec = new par[max*2];
for (int i=0; i<max; i++) vec[i] = ar[i];
delete[] ar; ar = vec;
max *= 2;
}
// ahora si que hay espacio para el nuevo string
pp = &ar[libre++];
// pp apunta a primero libre
pp->nombre = new char[strlen(s) +1];
strcpy(pp->nombre, s);
pp->valor = 0;
// valor inicial en 0
return pp->valor;
// destructor
asoc::~asoc ()
{
delete[] ar;
}
III-17
}
III-18
Departamento de Informática
Universidad Técnica Federico Santa María
Departamento de Informática
Lenguajes de Programación
Universidad Técnica Federico Santa María
Ejemplo: Operador [] (4/4)
Lenguajes de Programación
Operador de Función
int& asoc::imprimir ()
{
for (int i=0; i<libre; i++)
cout << ar[i].nombre << “:” << ar[i].valor << “\n”;
}
// el programa cuenta las palabras que se ingresan
// y luego imprime las estadísticas
main ()
{
const MAX = 256;
char palabra[MAX];
asoc aa(512);
• El operador () puede ser sobrecargado
• Es útil para definir tipos con una única
operación, o una que es predominante
• Una aplicación es para la definición de
iteradores
while (cin >> palabra) aa[palabra]++;
aa.imprimir();
}
III-19
Departamento de Informática
Universidad Técnica Federico Santa María
Ejemplo : Iterador
III-20
Departamento de Informática
Lenguajes de Programación
Universidad Técnica Federico Santa María
(1/2)
Lenguajes de Programación
Ejemplo : Iterador
class asoc {
friend class iterador_asoc;
par*
ar;
// arreglo de pares asociados
int
max;
// tamaño máximo del arreglo
int
libre;
// posición de primero libre
public:
asoc (int);
int& operator[] (const char*);
};
class iterador_asoc {
const asoc* aa;
// arreglo asociativo
int i
// indice actual en el arreglo
public:
iterador_asoc (const asoc& a) { aa = &a; i=0; }
par* operador() ()
// sobrecarga llamada afunción
{ return (i < aa->libre)? aa->ar[i++] : 0; }
};
III-21
(2/2)
// el programa cuenta las palabras que se ingresan
// y luego imprime las estadísticas
main ()
{
const MAX = 256;
char palabra[MAX];
asoc aa(512);
while (cin >> palabra) aa[palabra]++;
// imprimir las estadísticas
iterador_asoc proximo_par(aa);
par*
p;
while (p = proximo_par())
cout << p->nombre << “:” << p->valor << “\n”;
}
III-22
Documentos relacionados
Descargar