Dominando la sobrecarga de operadores en C++: ejemplos prácticos y mejores prácticas
Sobrecarga de operadores en C++
En este tutorial aprenderemos sobre la sobrecarga de operadores con la ayuda de ejemplos.
En C++, podemos cambiar la forma en que funcionan los operadores para tipos definidos por el usuario como objetos y estructuras. Esto se conoce como sobrecarga de operadores. Por ejemplo,
Supongamos que hemos creado tres objetos c1, c2 y resultado de una clase llamada Complejo que representa números complejos.
Dado que la sobrecarga de operadores nos permite cambiar cómo funcionan los operadores, podemos redefinir cómo funciona el operador + y usarlo para sumar los números complejos de c1 y c2 escribiendo el siguiente código:
resultado = c1 + c2;
en lugar de algo como
resultado = c1.sumarNumeros(c2);
Esto hace que nuestro código sea intuitivo y fácil de entender.
int, float, char, etc.Sintaxis para la sobrecarga de operadores en C++
Para sobrecargar un operador, usamos una función especial operator. Definimos la función dentro de la clase o estructura cuyos objetos/variables queremos que funcionen con el operador sobrecargado.
class NombreClase {
// ...
tipoRetorno operator simbolo(argumentos) {
// ...
}
// ...
};
Aquí,
tipoRetornoes el tipo de retorno de la función.operatores una palabra clave.simboloes el operador que queremos sobrecargar. Por ejemplo:+,<,-,++, etc.argumentosson los argumentos pasados a la función.
Sobrecarga de operadores unarios
Los operadores unarios operan sobre un solo operando. El operador de incremento ++ y decremento -- son ejemplos de operadores unarios.
Ejemplo 1: Sobrecarga del operador ++ (operador unario) como prefijo
// Sobrecargar ++ cuando se usa como prefijo
#include <iostream>
using namespace std;
class Contador {
private:
int valor;
public:
// Constructor para inicializar contador a 5
Contador() : valor(5) {}
// Sobrecargar ++ cuando se usa como prefijo
void operator ++ () {
++valor;
}
void mostrar() {
cout << "Contador: " << valor << endl;
}
};
int main() {
Contador contador1;
// Llama a la función "void operator ++ ()"
++contador1;
contador1.mostrar();
return 0;
}
Salida
Contador: 6
Aquí, cuando usamos ++contador1;, se llama a void operator ++ (). Esto aumenta el atributo valor del objeto contador1 en 1.
++ para aumentar valor en 100. Sin embargo, esto haría nuestro código confuso y difícil de entender. Es nuestro trabajo como programadores usar la sobrecarga de operadores de forma adecuada, consistente e intuitiva.El ejemplo anterior solo funciona cuando ++ se usa como prefijo. Para hacer que ++ funcione como postfijo usamos esta sintaxis:
void operator ++ (int) {
// código
}
Observe el int dentro de los paréntesis. Es la sintaxis usada para operadores unarios como postfijo; no es un parámetro de función.
Ejemplo 2: Sobrecarga del operador ++ (prefijo y postfijo)
// Sobrecargar ++ cuando se usa como prefijo y postfijo
#include <iostream>
using namespace std;
class Contador {
private:
int valor;
public:
// Constructor para inicializar contador a 5
Contador() : valor(5) {}
// Sobrecargar ++ cuando se usa como prefijo
void operator ++ () {
++valor;
}
// Sobrecargar ++ cuando se usa como postfijo
void operator ++ (int) {
valor++;
}
void mostrar() {
cout << "Contador: " << valor << endl;
}
};
int main() {
Contador contador1;
// Llama a la función "void operator ++ (int)"
contador1++;
contador1.mostrar();
// Llama a la función "void operator ++ ()"
++contador1;
contador1.mostrar();
return 0;
}
Salida
Contador: 6 Contador: 7
El Ejemplo 2 funciona cuando ++ se usa tanto como prefijo como postfijo. Sin embargo, no funciona si intentamos hacer algo como esto:
Contador contador1, resultado;
// Error
resultado = ++contador1;
Esto es porque el tipo de retorno de nuestra función operador es void. Podemos resolver este problema haciendo que Contador sea el tipo de retorno de la función operador.
// Devolver Contador cuando ++ se usa como prefijo
Contador operator ++ () {
// código
}
// Devolver Contador cuando ++ se usa como postfijo
Contador operator ++ (int) {
// código
}
Ejemplo 3: Devolver valor desde la función operador (operador ++)
#include <iostream>
using namespace std;
class Contador {
private:
int valor;
public:
// Constructor para inicializar contador a 5
Contador() : valor(5) {}
// Sobrecargar ++ cuando se usa como prefijo
Contador operator ++ () {
Contador temp;
// Aquí, valor es el atributo valor del objeto que llama
temp.valor = ++valor;
return temp;
}
// Sobrecargar ++ cuando se usa como postfijo
Contador operator ++ (int) {
Contador temp;
// Aquí, valor es el atributo valor del objeto que llama
temp.valor = valor++;
return temp;
}
void mostrar() {
cout << "Contador: " << valor << endl;
}
};
int main() {
Contador contador1, resultado;
// Llama a la función "Contador operator ++ ()"
resultado = ++contador1;
resultado.mostrar();
// Llama a la función "Contador operator ++ (int)"
resultado = contador1++;
resultado.mostrar();
return 0;
}
Salida
Contador: 6 Contador: 6
Aquí, hemos usado el siguiente código para la sobrecarga del operador prefijo:
// Sobrecargar ++ cuando se usa como prefijo
Contador operator ++ () {
Contador temp;
// Aquí, valor es el atributo valor del objeto que llama
temp.valor = ++valor;
return temp;
}
El código para la sobrecarga del operador postfijo es similar. Observe que hemos creado un objeto temp y devolvemos su valor a la función operador.
También observe el código
temp.valor = ++valor;
La variable valor pertenece al objeto contador1 en main() porque contador1 está llamando a la función, mientras que temp.valor pertenece al objeto temp.
Sobrecarga de operadores binarios
Los operadores binarios trabajan con dos operandos. Por ejemplo,
resultado = num + 9;
Aquí, + es un operador binario que trabaja con los operandos num y 9.
Cuando sobrecargamos el operador binario para tipos definidos por el usuario usando el código:
obj3 = obj1 + obj2;
La función operador es llamada usando el objeto obj1 y obj2 se pasa como argumento a la función.
Ejemplo 4: Sobrecarga de operador binario en C++
// Programa en C++ para sobrecargar el operador binario +
// Este programa suma dos números complejos
#include <iostream>
using namespace std;
class Complejo {
private:
float real;
float imag;
public:
// Constructor para inicializar real e imag a 0
Complejo() : real(0), imag(0) {}
void entrada() {
cout << "Ingrese parte real e imaginaria respectivamente: ";
cin >> real;
cin >> imag;
}
// Sobrecargar el operador +
Complejo operator + (const Complejo& obj) {
Complejo temp;
temp.real = real + obj.real;
temp.imag = imag + obj.imag;
return temp;
}
void salida() {
if (imag < 0)
cout << "Número complejo resultante: " << real << imag << "i";
else
cout << "Número complejo resultante: " << real << "+" << imag << "i";
}
};
int main() {
Complejo complejo1, complejo2, resultado;
cout << "Ingrese primer número complejo:\n";
complejo1.entrada();
cout << "Ingrese segundo número complejo:\n";
complejo2.entrada();
// complejo1 llama a la función operador
// complejo2 se pasa como argumento a la función
resultado = complejo1 + complejo2;
resultado.salida();
return 0;
}
Salida
Ingrese primer número complejo: Ingrese parte real e imaginaria respectivamente: 9 5 Ingrese segundo número complejo: Ingrese parte real e imaginaria respectivamente: 7 6 Número complejo resultante: 16+11i
En este programa, la función operador es:
Complejo operator + (const Complejo& obj) {
// código
}
En lugar de esto, también podríamos haber escrito esta función como:
Complejo operator + (Complejo obj) {
// código
}
Sin embargo,
- usar
&hace nuestro código eficiente al referenciar el objeto complejo2 en lugar de crear una copia dentro de la función operador. - usar
constse considera una buena práctica porque evita que la función operador modifique complejo2.

Aspectos a recordar en la sobrecarga de operadores en C++
- Dos operadores
=y&ya están sobrecargados por defecto en C++. Por ejemplo, para copiar objetos de la misma clase, podemos usar directamente el operador=. No necesitamos crear una función operador. - La sobrecarga de operadores no puede cambiar la precedencia y asociatividad de los operadores. Sin embargo, si queremos cambiar el orden de evaluación, se deben usar paréntesis.
- Hay 4 operadores que no se pueden sobrecargar en C++. Son:
::(resolución de ámbito).(selección de miembro).*(selección de miembro a través de puntero a función)?:(operador ternario)
Lecturas recomendadas:
- Cómo sobrecargar el operador de incremento correctamente
- Cómo sobrecargar el operador binario - para restar números complejos
Lenguaje C
- Operadores en C# – Guía completa de operadores en C#
- Operador ternario en C#: Guía concisa para expresiones condicionales
- Dominando la Sobrecarga de Métodos en C#: Conceptos, Ejemplos y Buenas Prácticas
- Dominando la Sobrecarga de Constructores en C#
- Dominando los Operadores en C++: Guía Completa con Ejemplos Prácticos
- Comentarios en C++: Mejores Prácticas para Código Legible y Mantenible
- Dominando las plantillas de clase en C++: guía práctica
- Operadores en C++ explicados: Tipos, ejemplos y programas de muestra
- Sobrecarga de operadores en C++: Guía práctica con ejemplos de código
- Lenguaje de Programación C++: Visión General y Características Clave
- Dominando la Sobrecarga de Operadores en Python: Guía Práctica