[C con Clase] Sobrecarga de operadores: Operaciones conmutativas

Steven Davidson srd4121 en njit.edu
Lun Mar 9 20:40:11 CET 2009


Hola Vicente,

vicente lozano wrote:
> Hola!
> 
> Estaba pensando, mientras leia un ejemplo de una clase fracciones,
> que quizas exista alguna forma de declarar algo como esto:
> 
> friend Fraccion operator+ ( Fraccion &fr, int & in)
> friend Fraccion operator+ ( Fraccion &fr, float & fl)
> friend Fraccion operator+ ( Fraccion &fr, double & do)
> 
> friend Fraccion operator+ ( void &anything, Fraccion &f)
> {
>  return (f+anything);
> }
> 
> Es posible? Es seguro?
> 

Tal y como está, no se puede por el tipo 'void &', aunque sí podrías 
usar un puntero a 'void'. De todas maneras, lo que quieres hacer se 
puede lograr a través de otro mecanismo propio de C++ llamado 
"plantillas" o "templates" en inglés. En tu caso, esto sería,

template< typename T >
Fraccion operator+( const T &sumando, const Fraccion &fraccion )
{
   ...
}

Esta función-plantilla serviría como una función general del operador +. 
a. Podemos implementar versiones concretas aun teniendo esta plantilla. 
Por ejemplo,

template<>
Fraccion operator+( const int &sumando, const Fraccion &fraccion )
{
   ...
}

Obviamente, las plantillas no van a solucionarte todos los problemas, 
por ejemplo, podemos tener lo siguiente:

Punto pt(4,3);
Fraccion f(1,2);

f = pt + f;

El compilador generará la sobrecarga del operador + correspondiente al 
tipo 'Punto', pero aún así, esto no resuelve el problema de sumar un 
punto a una fracción.


De todas maneras, los ejemplos que has escrito no requieren varias 
versiones, ya que C++ tiene reglas semánticas establecidas para cambiar 
de tipo para los tipos fundamentales. Por ello, sugiero crear una sola 
versión para el tipo de dato más "elevado" que es 'long double'. Esto es,

Fraccion operator+( const Fraccion &fr, long double sumando );

Si usamos cualquier otro tipo fundamental, éste será convertido 
implícitamente (promocionado) a 'long double'. Por ejemplo,

Fraccion f(1,2);
short int nNum=5;

f = f + nNum;

El valor en 'nNum' es convertido y pasado a 'long double'. Con esto, no 
necesitamos crear múltiples versiones.

Ahora bien, si tienes pensado implementar diferentes funcionalidades 
para cada versión del operador + dependiendo del tipo fundamental, 
entonces tendrás que realizar las sobrecargas explícitamente.


La otra posibilidad es que no necesitemos todas estas sobrecargas ya que 
podríamos simplemente usar el constructor de 'Fraccion'. Esto implica 
que sólo tenemos que implementar una sobrecarga del operador + que 
acepte dos objetos de tipo 'Fraccion'. Por ejemplo,

class Fraccion
{
   ...
   Fraccion( long double izq=0, long double der=1 );
};

Fraccion operator+( const Fraccion &izq, const Fraccion &der );

Podemos hacer lo siguiente,

Fraccion f(1,2);
short int nNum=5;

f = f + nNum;

Aquí, implícitamente hacemos lo siguiente:
operator+( f, Fraccion( (long double)nNum ) );


Espero haber aclarado la duda.

Steven





Más información sobre la lista de distribución Cconclase