Sobrecargando operadores

Agrupa todas las consultas sobre los lenguajes de programacion como C, C++, Python, Java ...

Sobrecargando operadores

Notapor lacabra25 » Vie Jun 19, 2009 9:52 am

Hola, tengo entendido que en C++ se pueden sobrecargar operadores para en lugar de llamar a la funcion, por ejemplo, "sumarvectores(a,b)" se pueda hacer "a+b", lo que no se es si se puede hacer tambien en C ¿puede sobrecargarse operadores en C? ¿como se sobrecargan los operadores?. Otra cosa, quiero sobrecargar operadores para una funcion en la que multiplico un escalar por una estructura vector que he echo en la que el escalar se pasa como argumento pero el vector pasa por referencia y no se si se podra sobrecargar los operadores para que poniendo "a*b" siendo por ejemplo a el vector la sobrecarga de operadores se encargue de poner "&a*b" ya que la funcion debe ser llamada como "multiplica_escalar_vector(b,&a)", no se si me explico. La idea es que el trabajo con los vectores sea igual que si fuesen los tipos con los que C trabaja en lugar de tener que estar recordando las funciones para operar con ellos, pero las funciones necesitan los vectores pasados por su puntero.
Esta cuenta ahora a pasado a la cuenta jhg
Avatar de Usuario
lacabra25
 
Mensajes: 222
Registrado: Mié Abr 02, 2008 9:45 pm
Ubicación: Tenerife (España)

Notapor Juanxo » Vie Jun 19, 2009 11:29 am

Buenas lacabra:
Yo no es que sea un gran entendido de c/c++, pero lo que tengo entendido es que la sobrecarga de operadores se realiza dentro de las clases, ergo......
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Notapor lacabra25 » Vie Jun 19, 2009 12:10 pm

Juanxo escribió:Buenas lacabra:
Yo no es que sea un gran entendido de c/c++, pero lo que tengo entendido es que la sobrecarga de operadores se realiza dentro de las clases, ergo......

Ya, entonces en C no se podria sino solo en C++, lo que tambien se me ha ocurrido es si se podria imitar la sobrecarga de operadores con las macros con algo como:

Código: Seleccionar todo
#define X+Y funcion(X,Y)


Lo que no se es si funcionara bien.
Esta cuenta ahora a pasado a la cuenta jhg
Avatar de Usuario
lacabra25
 
Mensajes: 222
Registrado: Mié Abr 02, 2008 9:45 pm
Ubicación: Tenerife (España)

Notapor Juanxo » Vie Jun 19, 2009 1:58 pm

Buenas lacabra:
A lo mejor funciona, pero lo que yo creo es que no podrá ser así, porque "x+y" sería como una string, no como variable x + variable y, no se si me explico
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Notapor Juan Carlos » Vie Jun 19, 2009 2:21 pm

Hola, bueno, aclarando un par de dudas:

En C no hay sobrecarga, mientras que en C++ si. Hay que aclarar que la sobrecarga no es necesaria definirla en una clase, bien podria definirse afuera, como una simple funcion de C.

Respecto a como pasar por referencia, hay que usar un operador especial propio de C++ (no existe en C) y es llamado operador de referencia.

Vemos, un ejemplo en C:

Código: Seleccionar todo
void funcion(int a, int *b) {
          a = a+1;
          *b = *b +1;
}

int a = 0;
int b = 0;

funcion(a, &b);

//Ahora, a == 0 y b == 1


Ahora,un ejemplo de C++:
Código: Seleccionar todo
void funcion(int a, int &b) {
          a = a+1;
          b = b +1;
}

int a = 0;
int b = 0;

funcion(a,b);

//Ahora, a == 0 y b == 1


En ambos casos, pido disculpas si la sintaxis no es correcta, hace unos cuantos meses que no programo en C++. Sin embargo, lo mas importante es la diferencia de los dos ejemplos.

En C, se necesita un operador de puntero ( *b en la definicion de la funcion), un operador de dereferencia ( *b al momento de hacer " *b=*b+1") y por ultimo un operador de direccion ( &b al momento del llamado)

Mientras, en C++ se simplifica usando el operador de referencia ( &b en la definicion de la funcion), ninguna otra sintaxis adicional es requerida.

Hay un par de cosas mas sobre la sobrecarga, pero dado que no recuerdo la sintaxis exacta, no lo puedo explicar sin ejemplos. Te recomiendo el Thinking in C++ de (esta en ingles y hay una version en castellano) donde explica muy bien la sobrecarga, no solo de operadores basicos como +,*, sino tambien otros operadores.

Saludos[/code]
Juan Carlos
 
Mensajes: 97
Registrado: Sab Jul 07, 2007 1:05 pm

Notapor Geo » Sab Jun 20, 2009 4:42 am

Todo lo que has mencionado al principio, son algunas de las cosas que se consideraron para agregar al lenguaje C++ y hacerlo un C "mejorado".

lacabra25 escribió:Ya, entonces en C no se podria sino solo en C++, lo que tambien se me ha ocurrido es si se podria imitar la sobrecarga de operadores con las macros con algo como:

Código: Seleccionar todo
#define X+Y funcion(X,Y)


Lo que no se es si funcionara bien.

No funcionará, debido a que estás intentando utilizar un operador (+) en la definición del texto que representa la macro. Haciéndolo al contrario (simulando una función) si funcionaría:

Código: Seleccionar todo
#define suma(a,b) a+b

Debido a que la "macro" es un texto que será sustituido por lo que se encuentre a la derecha, pero no puede incluir operadores ya definidos, pues esto confundiría fácilmente al compilador, ¿debería ejecutar una suma a+b o buscar una sustitución? O más aún, ¿por qué tratar en el código "a+b" como una macro y "c+d" como una operación suma?

Ahora, un detalle que quizá ya observaste, el código de una macro debe poder ejecutarse, es decir, la operación debe ya estar definida. En el ejemplo, a y b deben ser de tipo conocido y/o que para ellos esté ya definida la operación +. La sobrecarga de operadores se introdujo para poder hacer uso de los operadores del lenguaje con nuevos tipos definidos por el usuario, de manera que se tuviera una forma "más natural" de trabajar con estos nuevos tipos.

Si por alguna razón necesitas hacer uso de la sobrecarga de operadores, fácilmente puedes pasarte a C++ y usarlo como un C "ampliado" :).
La imaginación es el límite.
Visita mi blog en inglés o en español.
Geo
 
Mensajes: 244
Registrado: Jue Ago 10, 2006 3:51 am
Ubicación: México

Notapor lacabra25 » Sab Jun 20, 2009 10:29 am

Entiendo, sobrecarga de operadores solo en C++, solo una cosa, ¿seria posible tener la parte de los vectores junto con la sobrecarga de operadores en C++ y usarlo en codigo en C haciendo un includo de la cabecera C++ de los vectores y asi usarlos en otra parte de codigo que este en C (mezclar C con C++ en definitiva)? y ¿como se realizaria la sobrecarga de operadores en C++?

Gracias a todos por la ayuda.
Esta cuenta ahora a pasado a la cuenta jhg
Avatar de Usuario
lacabra25
 
Mensajes: 222
Registrado: Mié Abr 02, 2008 9:45 pm
Ubicación: Tenerife (España)

Notapor Geo » Dom Jun 21, 2009 5:13 pm

lacabra25 escribió:Entiendo, sobrecarga de operadores solo en C++, solo una cosa, ¿seria posible tener la parte de los vectores junto con la sobrecarga de operadores en C++ y usarlo en codigo en C haciendo un includo de la cabecera C++ de los vectores y asi usarlos en otra parte de codigo que este en C (mezclar C con C++ en definitiva)?

No, no es posible. Aunque la programación orientada a objetos es posible en C, no lo es la adición de nuevos "tipos" como en C++. Puedes incluir código C en C++, pero no a la inversa.

lacabra25 escribió:y ¿como se realizaria la sobrecarga de operadores en C++?

Se realiza de manera similar a una función, con la característica particular de que se hace uso de la palabra operator, algo como esto:

Código: Seleccionar todo
void operator*( int escalar, MiVector& v ) {
   for ( int i = 0; i < v.tamanio; i++ ) {
      v.valores[ i ] *= escalar;
   }
}

En este caso, se ha sobrecargado el operador * para el caso en que tenga como parámetros un int y un tipo MiVector.

Algunos detalles sobre la sobrecarga de operadores: Las funciones de sobrecarga pueden declararse como funciones miembro de una clase, o como funciones externas a la clase (funciones no miembro).
Cuando el tipo que se está definiendo (la clase), se empleará como parámetro izquierdo del operador (operadores binarios como +, -, *), puede ser una función miembro o no, mientras que, si será un parámetro del lado derecho, debe declararse como una función no miembro (externa a la clase).
En el código que puse, se trata de una función externa a la clase MiVector, pues el tipo MiVector se recibe como parámetro del lado derecho (escalar*MiVector), las variables tamanio y valores son miembros de la clase MiVector, siendo la primera un entero que indica el número de valores y la segunda un puntero a los valores de MiVector.
Debido a que las funciones que no son miembro de una clase no pueden acceder directamente a las variables miembro de dicha clase, si ambas variables (tamanio y valores) fueron declaradas como privadas en la clase MiVector, la función sobrecargada debe declararse como "amiga" de la clase para poder acceder a ellas como se está haciendo en el código que puse.

Con variables privadas, la declaración de la clase MiVector sería más o menos así:
Código: Seleccionar todo
class MiVector {
   // la función debe ser "amiga" para poder acceder a las variables
   // miembro
   friend void operator*( int escalar, MiVector& v );

private:
   int* valores;
   int tamanio;
};

Y de esta forma con variables públicas:
Código: Seleccionar todo
class MiVector {
   // las variables son públicas, no se necesita ninguna declaración
   // especial para que la función de sobrecarga acceda a las variables

public:
   int* valores;
   int tamanio;
};

Por supuesto, la declaración de la clase está incompleta, espero que se entienda el ejemplo :).

Ahora, con la función de sobrecarga que escribimos, esto es válido:
Código: Seleccionar todo
MiVector v;
int escalar = 2;

escalar * v;

pero esto no:

Código: Seleccionar todo
v * escalar;


Esto porque no se ha sobrecargado el operador * para que reciba un tipo MiVector como parámetro izquierdo y un int como parámetro derecho. Es decir, hay que sobrecargar dos veces el operador si deseamos que su funcionamiento sea conmutativo :).

En internet hay muchos recursos para leer sobre sobrecarga de operadores, por ejemplo en C con clase: http://c.conclase.net/curso/index.php?cap=035

Yo tengo un libro que recomiendo mucho para quienes deseamos aprender C++: C++ Cómo programar de Deitel, yo tengo la cuarta edición, que me gusta mucho pues la primera parte está dedicada a la programación estructurada ("el C en C++"), para luego continuar con las clases y la orientación a objetos (en la quinta edición cambió el enfoque, aunque no he tenido oportunidad de revisarla).

Por último, yo también estoy aprendiendo y no manejo estos temas a la perfección, pero estamos aquí para compartir y echarnos la mano :).
La imaginación es el límite.
Visita mi blog en inglés o en español.
Geo
 
Mensajes: 244
Registrado: Jue Ago 10, 2006 3:51 am
Ubicación: México

Notapor lacabra25 » Mar Jun 23, 2009 9:29 am

Gracias por la informacion Geo.
Esta cuenta ahora a pasado a la cuenta jhg
Avatar de Usuario
lacabra25
 
Mensajes: 222
Registrado: Mié Abr 02, 2008 9:45 pm
Ubicación: Tenerife (España)


Volver a Sobre lenguajes de programación

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado