lunes, 7 de julio de 2008

Sobrecarga de funciones y operadores en C++ (Parte 2)

CHenry [chenry@lab.matcom.uh.cu]

Sobrecarga de operadores binarios
Los operadores binarios se pueden sobrecargar pasando a la función dos argumentos. El primer argumento es el operando izquierdo del operador sobrecargado y el segundo argumento es el operando derecho. Suponiendo dos objetos x e y de una clase c, se define un operador binario + sobrecargado. Entonces x + y se puede interpretar como operator+(x,y) o como x.operator+(y)


Un operador binario puede, por consiguiente, ser definido:
- como un amigo de dos argumentos
- como una función miembro de un argumento (caso más frecuente)
- nunca los dos a la vez

Sobrecarga de un operador binario como función miembro
El siguiente ejemplo muestra cómo sobrecargar un operador binario como una función miembro:
class binario

{
  int x;
  public:
  binario() {x=0;}
  binario(int a) {x=a;}
  binario operator + (binario &);
  void visualizar() {cout<<x<<endl;
};

binario binario::operator +(binario &a)
{
  binario aux;
  aux.x=x+a.x;
  return aux;
}

void main()
{
  binario primero(2),segundo(4),tercero;
  tercero = primero + segundo;
  tercero.visualizar();
}

La salida del programas es 6.

Sobrecarga de un operador binario como una función amiga
class binario
{
  int x;
  public:
  binario() {x=0;}
  binario(int a) {x=a;}
  friend binario operator + (binario &,binario &);
  void visualizar() {cout<<x<<endl;
};

binario binario::operator +(binario &a,binario &b)
{
  binario aux;
  aux.x=a.x+b.x;
  return aux;
}

void main()
{
  binario primero(2),segundo(4),tercero;
  tercero = primero + segundo;
  tercero.visualizar();
}
La salida del programa será 6.

La función operador binario +() está declarada; debido a que es una función amiga, el sistema no pasa el puntero this implícitamente y, por consiguiente, se debe pasar el objeto binario explícitamente con ambos argumentos. Como consecuencia, el primer argumento de la función miembro se convierte en el operando izquierdo de este operador y el segundo argumento se pasa como operando derecho.

Sobrecargando el operador de llamada a funciones ( )

Uno de los operadores más usuales es el operador de llamada a función y puede ser sobrecargado. La llamada a función se considera como un operador binario
expresión principal (lista de expresiones)

Donde expresión principal es un operando y lista de expresiones (que puede ser vacía) es el otro operando.
La función operador correspondiente es operator() y puede ser definida por el usuario para una clase c sólo mediante una función miembro no estática.
x(i) equivale a x.operator() (i)
x(i,j) equivale a x.operator()(x,y)

Sobrecargando el operador subíndice [ ]

El operador [] se utiliza normalmente como índice de arrays. En realidad este operador realiza una función útil; ocultar la aritmética de punteros. Por ejemplo, si se tiene el siguiente array: char nombre[30]; y se ejecuta una sentencia tal como car = nombre[15]; el operador [] dirige la sentencia de asignación para sumar 15 a la dirección base del array nombre para localizar los datos almacenados en esta posición de memoria.

En C++ se puede sobrecargar este operador y proporciona muchas extensiones útiles al concepto de subíndices de arrays. [] se considera un operador binario porque tiene dos argumentos. En el ejemplo p=x[i]

Los argumentos son x e i. La función operador correspondiente es operator []; ésta puede ser definida para una clase x sólo mediante un función miembro. La expresión x[i] donde x es un objeto de una determinada clase, se interpreta como x.operator[](y).

Sobrecarga de operadores de flujo

Las sentencias de flujos se utilizan para entradas y salidas. Los flujos no son parte de C++, pero se implementan como clases en la biblioteca de C++. Las declaraciones para estas clases se almacenan en el archivo de cabecera iostream.h. En C++ es posible sobrecargar los operadores de flujo de entrada y salida de modo que pueda manipular cualquier sentencia de flujo que incluya cualquier tipo de clase. Como se definen en el archivo de cabecera iostream.h, estos operadores trabajan con todos los tipos predefinidos, tales como int, long, double,char. Sobrecargando estos los operadores de flujo de entrada y salida, estos pueden además manipular cualquier tipo de objetos de clases.
Ejemplo de sobrecarga de los flujos << y >>

class punto
{
  int x,y;
  public:
  punto() {x=y=0;}
  punto (int xx,int yy) { x=xx;y=yy;}
  void fijarx(int xx) { x=xx;}
  void fijary(int yy) {y=yy;}
  int leerx() {return x;}
  int leery() {return y;}
  friend ostream& operator << (ostream& os,const punto &p);
  friend istream& operator >> (istream& is,const punto &p);
};

void main()
{
  punto p;
  cout<<p<<endl;
  p.fijarx(50);
  p.fijary(100);
  cout<<p<<endl;
  cout <<"introducir los valores de x e y\n";
  cin>>p;
  cout<<"se ha introducido"<<p;
}

ostream& operator<<(ostream &os,punto &p)
{
  os <<"x= "<<p.x<<",y= "<<p.y;
  return os;
}

istream& operator>>(istream &is,punto &p)
{
  is >>p.x>>p.y;
  return is;
}
Es posible poner en cascada múltiples objetos en una sentencia de flujo de salida:
punto p1,p2, p3;
cout<<p1<<":"<<p2<<":"<<p3;

No solo necesitamos pensar como programadores, conocer las características de cada lenguaje nos permite elegir la mejor opción para la construcción de un software que cumpla con las expectativas de la comunidad.
Quejas y sugerencias mailto:chenry@lab.matcom.uh.cu



Artículos relacionados


No hay comentarios: