Daniel Garcia

sábado, julio 17, 2010

SOBRECARGA DE OPERADORES EN C

 

Sobrecarga de operadores.

La sobrecarga de operadores permite redefinir ciertos operadores, como '+' y '-', para usarlos con las clases que hemos definido. Se llama sobrecarga de operadores porque estamos reutilizando el mismo operador con un número de usos diferentes, y el compilador decide cómo usar ese operador dependiendo sobre qué opera.

La sobrecarga de operadores sólo se puede utilizar con clases, no se pueden redefinir los operadores para los tipos simples predefinidos.

Los operadores lógicos && y || pueden ser sobrecargados para las clases definidas por el programador, pero no funcionarán como operadores de short circuit. Todos los miembros de la construcción lógica serán evaluados sin ning´n problema en lo que se refiere a la salida. Naturalmente los operadores lógicos predefinidos continuarán siendo operadores de short circuit como era de esperar, pero no los sobrecargados.

Los siguientes operadores no pueden ser sobrecargados:

    • El operador ternario ?.
    • El operador de acceso a una clase o estructura : .
    • El operador scope ::

Sobrecarga de operadores binarios.

Un operador binario es el que tiene dos operandos.

Ejemplo donde sobrecargamos el operador + para, a partir de dos cajas, crear otra de dimensiones igual a la suma de las dimensiones de las cajas dadas:

#include <iostream.h>

class Caja {

double longitud;

double anchura, altura;

public:

void set(int l, int w, int h) {longitud = l; anchura = w; altura = h;}

double volumen(void) {return longitud * anchura * altura;}

Caja operator+(Caja a);

};

Caja operator+(Caja a) {

Caja temp;

temp.longitud = longitud + a.longitud;

temp.anchura = anchura + a.anchura;

temp.altura = altura + a.altura;

return temp;

}

main() {

Caja pequeña, mediana, grande;

Caja temp;

pequeña.set(2, 4, 5);

mediana.set(5, 6, 8);

grande.set(8, 10, 12);

cout << 'El volumen es ' << pequeña.volumen() << '\n';

cout << 'El volumen es ' << mediana.volumen() << '\n';

cout << 'El volumen es ' << grande.volumen() << '\n';

temp = pequeña + mediana;

cout << 'El nuevo volumen es ' << temp.volumen() << '\n';

}

El resultado de la ejecución será:

El volumen es 40.

El volumen es 240.

El volumen es 960.

El volumen es 840.

Observamos que :

· El operador se llama desde la clase que precede al operador, y el objeto que le sigue es enviado como parámetro. Esto significa que el parámetro (a) es mediana.

· El operador puede acceder a los miembros privados del parámetro que es enviado. En el ejemplo, accede a a.longitud, a.anchura, a.altura.

Operadores amigos

#include <iostream.h>

class Caja {

double longitud;

double anchura, altura;

public:

void set(int l, int w, int h) {longitud = l; anchura = w; altura = h;}

int volumen(void) {return longitud * anchura * altura;}

friend Caja operator+(Caja a, Caja b); // Add two Cajas

friend Caja operator+(int a, Caja b); // Add a constant to a Caja

friend Caja operator*(int a, Caja b); // Multiply a Caja by a constant

};

Caja operator+(Caja a, Caja b) {

Caja temp;

temp.longitud = a.longitud + b.longitud;

temp.anchura = a.anchura + b.anchura;

temp.altura = a.altura + b.altura;

return temp;

}

Caja operator+(int a, Caja b) { // Add a constant to a Caja

Caja temp;

temp.longitud = a + b.longitud;

temp.anchura = a + b.anchura;

temp.altura = a + b.altura;

return temp;

}

Caja operator*(int a, Caja b) { // Multiply a Caja by a constant

Caja temp;

temp.longitud = a * b.longitud;

temp.anchura = a * b.anchura;

temp.altura = a * b.altura;

return temp;

}

main() {

Caja pequeña, mediana, grande;

Caja temp;

pequeña.set(2, 4, 5);

mediana.set(5, 6, 8);

grande.set(8, 10, 12);

cout << 'El volumen es ' << pequeña.volumen() << '\n';

cout << 'El volumen es ' << mediana.volumen() << '\n';

cout << 'El volumen es ' << grande.volumen() << '\n';

temp = pequeña + mediana;

cout << 'El nuevo volumen es ' << temp.volumen() << '\n';

temp = 10 + pequeña;

cout << 'El nuevo volumen es ' << temp.volumen() << '\n';

temp = 4 * grande;

cout << 'El nuevo volumen es ' << temp.volumen() << '\n';

}

El resultado de la ejecución es:

El volumen es 40

El volumen es 240.

El volumen es 960.

El nuevo volumen es 840.

El nuevo volumen es 2520.

El nuevo volumen es 61440.

· Hemos sobrecargado los operadores + y *, declarándolos como funciones amigas, de forma que podemos utilizar funciones con dos parámetros. Si no los hubiésemos utilizado la construcción friend, la función sería parte de uno de los objetos y ese objeto sería el objeto al que se le pasa el mensaje.

· No hay límite superior para el número de operadores o de funciones sobrecargadas. Se puede definir cualquier número de operadores sobrecargados, siempre que difieran en la lista de argumentos.

· Se observa que la implementación de las funciones amigas no es realmente parte de la clase porque el nombre de la clase no precede al de la función.

Sobrecarga de operadores unarios.

Un operador unario sólo tiene un operando. Ejemplos de operadores unitarios son ++ y --.

#include <iostream.h>

class Burrito {

private:

int amtbeef, amtbean;

public:

Burrito(int beef, int bean) {

amtbeef = beef;

amtbean = bean;

}

Burrito operator ++() {

amtbeef++; amtbean++;

return Burrito(amtbeef, amtbean);

}

int getBeef() { return amtbeef; }

};

main() {

Burrito b1(5,10);

cout << 'Burrito #1 has' << b1.getBeef() << 'ounces of beef.' << '\n';

b1++;

cout << 'Now Burrito #1 has' << b1.getBeef() << 'ounces of beef.'<< '\n';

}

Vemos que sobrecargar un operador unario es muy similar a la forma en que se hace para uno binario. De hecho, la única diferencia real es que ahora no se pasa ningún parámetro al operador, ya que ahora sólo hay un operando, que es el objeto cuyo operador se usa.

Hay si embargo una pequeña cuestión que debe tenerse en cuenta cuando se sobrecargan los operadores ++ y --. Sabemos que b = ++a; es diferente a b=a++;. La primera expresión equivale a a = a +1; b = a;, mientras que la segunda es : b = a; a = a +1;. Sin embargo, cuando se sobrecarga el operador ++ (o el --) no se puede hacer distinción entre estas dos situaciones. Los dos usos del operador tienen el mismo efecto.