Diferencia entre revisiones de «Sobrecarga de operadores unarios (Programación)»

Línea 1: Línea 1:
 
<div align="justify">{{Definición|Nombre= Sobrecarga de operadores unarios |imagen= |concepto=Se llama sobrecarga de operadores cuando reutilizando el mismo operador con un número de usos diferentes, y el compilador decide como usar ese operador dependiendo sobre qué opera.}}  
 
<div align="justify">{{Definición|Nombre= Sobrecarga de operadores unarios |imagen= |concepto=Se llama sobrecarga de operadores cuando reutilizando el mismo operador con un número de usos diferentes, y el compilador decide como usar ese operador dependiendo sobre qué opera.}}  
 
'''Sobrecarga de operadores unarios (Programación)'''.  Los operadores unarios susceptibles de sobrecarga son:
 
'''Sobrecarga de operadores unarios (Programación)'''.  Los operadores unarios susceptibles de sobrecarga son:
* Operadores unarios + y -  
+
·        Operadores unarios + y -  
* Operadores unarios de incremento ++ y decremento --   
+
·        [[Operadores aritméticos|Operadores unarios de incremento ++ y decremento --]]  
* [[Operadores de puntero|Operadores de puntero]]:  referencia &  e indirección *   
+
·        [[Operadores de puntero|Operadores de puntero]]:  referencia &  e indirección *   
* [[Operadores de manejo de bits|Operador de manejo de bits]] ("bitwise") complemento a uno ~  
+
·        [[Operadores de manejo de bits|Operador de manejo de bits]] ("bitwise") complemento a uno ~  
* [[Operadores lógicos|Operador de negación lógica  ! ]]
+
·        [[Operadores lógicos|Operador de negación lógica  ! ]]
* Asignación y desasignación dinámica de memoria: [[Operador new|new]]  y [[Operador delete|delete]]
+
·        Asignación y desasignación dinámica de memoria: [[Operador new|new]]  y [[Operador delete|delete]]
 
==Sobrecarga de operadores ++ y --==
 
==Sobrecarga de operadores ++ y --==
Los [[Operadores|operadores]] incremento ++ y decremento-- se sobrecargan de forma distinta según se trate de los "pre" o "post" operadores. Es decir, suponiendo que @ representa uno de ellos, la sobrecarga es distinta según se trate de la expresión @x o x@.
+
Los [[Operadores|operadores]]incremento ++ y decremento-- se sobrecargan de forma distinta según se trate de los "pre" o "post" operadores. Es decir, suponiendo que @ representa uno de ellos, la sobrecarga es distinta según se trate de la expresión @x o x@.
En el caso de los preoperadores ++/--, la sobrecarga para los miembros de una clase C puede hacerse de dos formas
+
En el caso de los preoperadores ++/--, la sobrecarga para los miembros de una clase C puede hacerse de dos formas  
 
 
a-  Declarando una función-miembro no estática, que no acepte argumentos del tipo:
 
a-  Declarando una función-miembro no estática, que no acepte argumentos del tipo:
C& C::operator++();
+
C& C::operator++();
 
b-  Declarando una función no miembro (generalmente friend) que acepte un argumento.
 
b-  Declarando una función no miembro (generalmente friend) que acepte un argumento.
C& operator++(C& c);
+
C& operator++(C& c);
 
Según lo anterior, y dependiendo de la declaración, la expresión @x puede ser interpretada como cualquiera de las dos formas:
 
Según lo anterior, y dependiendo de la declaración, la expresión @x puede ser interpretada como cualquiera de las dos formas:
a- x.operator@()
+
a- x.operator@()
b- operator@(x)
+
b- operator@(x)
 
Si han sido declaradas ambas formas, se aplica la congruencia estándar de argumentos para resolver cualquier posible ambigüedad.
 
Si han sido declaradas ambas formas, se aplica la congruencia estándar de argumentos para resolver cualquier posible ambigüedad.
 
===  Sobrecarga del operador preincremento ++X===
 
===  Sobrecarga del operador preincremento ++X===
 
La técnica a seguir y los problemas derivados de la sobrecarga de operadores unarios, se muestran en el siguiente ejemplo  
 
La técnica a seguir y los problemas derivados de la sobrecarga de operadores unarios, se muestran en el siguiente ejemplo  
int x = 5, y      // L.1:
+
int x = 5, y      // L.1:
y = ++x;          // L.2:
+
y = ++x;          // L.2:
cout << "x == " << x << "; y == " << y << endl;
+
cout << "x == " << x << "; y == " << y << endl;
Salida:
+
Salida:
x == 6; y == 6
+
x == 6; y == 6
 
En L.1 se declaran dos variables tipo int y se inicializa una de ellas, la otra contiene basura. La sentencia L.2 se ejecuta de derecha a izquierda:
 
En L.1 se declaran dos variables tipo int y se inicializa una de ellas, la otra contiene basura. La sentencia L.2 se ejecuta de derecha a izquierda:
 
El valor 5 de x es incrementado, pasando a valer 6
 
El valor 5 de x es incrementado, pasando a valer 6
 
El valor basura de y es sustituido por el valor 6 de x.
 
El valor basura de y es sustituido por el valor 6 de x.
 
===  Sobrecarga del operador predecremento --@===
 
===  Sobrecarga del operador predecremento --@===
#include <iostream>
+
#include <iostream>
using namespace std;
+
using namespace std;
class Entero {
+
 
  public: int x;
+
class Entero {
  friend Entero& operator++(Entero&);
+
  public: int x;
  friend Entero& operator--(Entero&);
+
  friend Entero& operator++(Entero&);
};
+
  friend Entero& operator--(Entero&);
Entero& operator++ (Entero& e) {
+
};
  e.x = e.x + e.x;
+
Entero& operator++ (Entero& e) {
  return e;
+
  e.x = e.x + e.x;
}
+
  return e;
Entero& operator-- (Entero& e) {
+
}
  e.x = e.x / 2;
+
Entero& operator-- (Entero& e) {
  return e;
+
  e.x = e.x / 2;
}
+
  return e;
void main () {      // ==============
+
}
  Entero e1, e2, e3;
+
 
  e1.x = 5;
+
void main () {      // ==============
  e3 = ++e2 = ++e1;
+
  Entero e1, e2, e3;
  cout << " e1 = " << e1.x << "; e2 = " << e2.x    
+
  e1.x = 5;
  e3 = --e2 = --e1;
+
  e3 = ++e2 = ++e1;
  cout << " e1 = " << e1.x << "; e2 = " << e2.x
+
  cout << " e1 = " << e1.x << "; e2 = " << e2.x
}
+
     
Salida:
+
  e3 = --e2 = --e1;
e1 = 10; e2 = 10; e3 = 10
+
  cout << " e1 = " << e1.x << "; e2 = " << e2.x
e1 = 5; e2 = 5; e3 = 5
+
     
 +
}
 +
Salida:
 +
e1 = 10; e2 = 10; e3 = 10
 +
e1 = 5; e2 = 5; e3 = 5
 
===  Sobrecarga de los post-operadores  X++ X--===
 
===  Sobrecarga de los post-operadores  X++ X--===
 
Los postoperadores incremento ++ y decremento -- solo pueden ser sobrecargados definiendo las funciones-operador de dos formas:
 
Los postoperadores incremento ++ y decremento -- solo pueden ser sobrecargados definiendo las funciones-operador de dos formas:
# Declarando una función miembro no estática que acepte un entero como argumento.  Ejemplo:
+
1- Declarando una función miembro no estática que acepte un entero como argumento.  Ejemplo:
C C::operator++(int);  
+
C C::operator++(int);  
# Declarando una función no miembro (generalmente friend) que acepte un objeto de la clase y un entero como argumentos (en este orden).  Ejemplo:
+
2- Declarando una función no miembro (generalmente friend) que acepte un objeto de la clase y un entero como argumentos (en este orden).  Ejemplo:
C operator-- (C&, int);
+
C operator-- (C&, int);
 
Dependiendo de la declaración, si @ representa un post-operador unitario (++ o --), la expresión x@ puede ser interpretada como cualquiera de las dos formas:
 
Dependiendo de la declaración, si @ representa un post-operador unitario (++ o --), la expresión x@ puede ser interpretada como cualquiera de las dos formas:
# x.operator@(int)
+
1-  x.operator@(int)
# operator@(x, int)
+
2-  operator@(x, int)
 
== Sobrecarga del operador de indirección==
 
== Sobrecarga del operador de indirección==
 
El operador de indirección * es un preoperador unario, por lo que su sobrecarga puede ser efectuada de cualquiera de las formas a o b  
 
El operador de indirección * es un preoperador unario, por lo que su sobrecarga puede ser efectuada de cualquiera de las formas a o b  
Línea 70: Línea 73:
 
== Sobrecarga del operador de negación lógica==
 
== Sobrecarga del operador de negación lógica==
 
El operador NOT de negación lógica ( ! ) está relacionado con su contrario (que no tiene nombre ni representación). Por ejemplo, la expresión:
 
El operador NOT de negación lógica ( ! ) está relacionado con su contrario (que no tiene nombre ni representación). Por ejemplo, la expresión:
if (!c) { /* ... */ }
+
if (!c) { /* ... */ }
 
Genera un error de compilación: 'operator!' not implemented in type 'C'..., en el que se indica que el operador NOT de negación lógica no está definido para objetos de la clase. Sin embargo, podemos observar que un intento análogo sin el operador:
 
Genera un error de compilación: 'operator!' not implemented in type 'C'..., en el que se indica que el operador NOT de negación lógica no está definido para objetos de la clase. Sin embargo, podemos observar que un intento análogo sin el operador:
if (c) { /* ... */ }
+
if (c) { /* ... */ }
 
También produce un error, aunque en este caso la indicación es más ambigüa: Illegal structure operation in function...(Borland) o: conditional expression of type 'class C' is illegal (Visual C++). En este último caso el compilador está indicando que no sabe como convertir la expresión entre paréntesis (c) a un tipo bool. La sentencia if(<condicion>)... espera recibir una expresión <condicion> que se resuelva en un bool
 
También produce un error, aunque en este caso la indicación es más ambigüa: Illegal structure operation in function...(Borland) o: conditional expression of type 'class C' is illegal (Visual C++). En este último caso el compilador está indicando que no sabe como convertir la expresión entre paréntesis (c) a un tipo bool. La sentencia if(<condicion>)... espera recibir una expresión <condicion> que se resuelva en un bool
 
Ambos inconvenientes pueden resolverse adoptando las medidas pertinentes. El primero sobrecargando el operador NOT para objetos de la clase. El segundo proporcionando una conversión de usuario que permita al compilador transformar un tipo C en un bool  
 
Ambos inconvenientes pueden resolverse adoptando las medidas pertinentes. El primero sobrecargando el operador NOT para objetos de la clase. El segundo proporcionando una conversión de usuario que permita al compilador transformar un tipo C en un bool  

Revisión del 12:52 17 nov 2012

Sobrecarga de operadores unarios (Programación)
Información sobre la plantilla
Concepto:Se llama sobrecarga de operadores cuando reutilizando el mismo operador con un número de usos diferentes, y el compilador decide como usar ese operador dependiendo sobre qué opera.

Sobrecarga de operadores unarios (Programación). Los operadores unarios susceptibles de sobrecarga son: · Operadores unarios + y - · Operadores unarios de incremento ++ y decremento -- · Operadores de puntero: referencia & e indirección * · Operador de manejo de bits ("bitwise") complemento a uno ~ · Operador de negación lógica ! · Asignación y desasignación dinámica de memoria: new y delete

Sobrecarga de operadores ++ y --

Los operadoresincremento ++ y decremento-- se sobrecargan de forma distinta según se trate de los "pre" o "post" operadores. Es decir, suponiendo que @ representa uno de ellos, la sobrecarga es distinta según se trate de la expresión @x o x@. En el caso de los preoperadores ++/--, la sobrecarga para los miembros de una clase C puede hacerse de dos formas a- Declarando una función-miembro no estática, que no acepte argumentos del tipo: C& C::operator++(); b- Declarando una función no miembro (generalmente friend) que acepte un argumento. C& operator++(C& c); Según lo anterior, y dependiendo de la declaración, la expresión @x puede ser interpretada como cualquiera de las dos formas: a- x.operator@() b- operator@(x) Si han sido declaradas ambas formas, se aplica la congruencia estándar de argumentos para resolver cualquier posible ambigüedad.

Sobrecarga del operador preincremento ++X

La técnica a seguir y los problemas derivados de la sobrecarga de operadores unarios, se muestran en el siguiente ejemplo int x = 5, y // L.1: y = ++x; // L.2: cout << "x == " << x << "; y == " << y << endl; Salida: x == 6; y == 6 En L.1 se declaran dos variables tipo int y se inicializa una de ellas, la otra contiene basura. La sentencia L.2 se ejecuta de derecha a izquierda: El valor 5 de x es incrementado, pasando a valer 6 El valor basura de y es sustituido por el valor 6 de x.

Sobrecarga del operador predecremento --@

  1. include <iostream>

using namespace std;

class Entero {

 public: int x;
 friend Entero& operator++(Entero&);
 friend Entero& operator--(Entero&);

}; Entero& operator++ (Entero& e) {

 e.x = e.x + e.x;
 return e;

} Entero& operator-- (Entero& e) {

 e.x = e.x / 2;
 return e;

}

void main () { // ==============

 Entero e1, e2, e3;
 e1.x = 5;
 e3 = ++e2 = ++e1;
 cout << " e1 = " << e1.x << "; e2 = " << e2.x
      
 e3 = --e2 = --e1;
 cout << " e1 = " << e1.x << "; e2 = " << e2.x
      

} Salida: e1 = 10; e2 = 10; e3 = 10 e1 = 5; e2 = 5; e3 = 5

Sobrecarga de los post-operadores X++ X--

Los postoperadores incremento ++ y decremento -- solo pueden ser sobrecargados definiendo las funciones-operador de dos formas: 1- Declarando una función miembro no estática que acepte un entero como argumento. Ejemplo: C C::operator++(int); 2- Declarando una función no miembro (generalmente friend) que acepte un objeto de la clase y un entero como argumentos (en este orden). Ejemplo: C operator-- (C&, int); Dependiendo de la declaración, si @ representa un post-operador unitario (++ o --), la expresión x@ puede ser interpretada como cualquiera de las dos formas: 1- x.operator@(int) 2- operator@(x, int)

Sobrecarga del operador de indirección

El operador de indirección * es un preoperador unario, por lo que su sobrecarga puede ser efectuada de cualquiera de las formas a o b

Sobrecarga del operador de negación lógica

El operador NOT de negación lógica ( ! ) está relacionado con su contrario (que no tiene nombre ni representación). Por ejemplo, la expresión: if (!c) { /* ... */ } Genera un error de compilación: 'operator!' not implemented in type 'C'..., en el que se indica que el operador NOT de negación lógica no está definido para objetos de la clase. Sin embargo, podemos observar que un intento análogo sin el operador: if (c) { /* ... */ } También produce un error, aunque en este caso la indicación es más ambigüa: Illegal structure operation in function...(Borland) o: conditional expression of type 'class C' is illegal (Visual C++). En este último caso el compilador está indicando que no sabe como convertir la expresión entre paréntesis (c) a un tipo bool. La sentencia if(<condicion>)... espera recibir una expresión <condicion> que se resuelva en un bool Ambos inconvenientes pueden resolverse adoptando las medidas pertinentes. El primero sobrecargando el operador NOT para objetos de la clase. El segundo proporcionando una conversión de usuario que permita al compilador transformar un tipo C en un bool

Puede Consultar

Fuente