Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Industrial programming >> Lenguaje C

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.

Nota: No podemos usar la sobrecarga de operadores para tipos de datos fundamentales como 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í,


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.

Nota: Cuando sobrecargamos operadores, podemos hacer que funcionen de cualquier manera. Por ejemplo, podríamos haber usado ++ 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,

Dominando la sobrecarga de operadores en C++: ejemplos prácticos y mejores prácticas

Aspectos a recordar en la sobrecarga de operadores en C++

  1. 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.
  2. 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.
  3. Hay 4 operadores que no se pueden sobrecargar en C++. Son:
    1. :: (resolución de ámbito)
    2. . (selección de miembro)
    3. .* (selección de miembro a través de puntero a función)
    4. ?: (operador ternario)

Lecturas recomendadas:

Lenguaje C

  1. Operadores en C# – Guía completa de operadores en C#
  2. Operador ternario en C#: Guía concisa para expresiones condicionales
  3. Dominando la Sobrecarga de Métodos en C#: Conceptos, Ejemplos y Buenas Prácticas
  4. Dominando la Sobrecarga de Constructores en C#
  5. Dominando los Operadores en C++: Guía Completa con Ejemplos Prácticos
  6. Comentarios en C++: Mejores Prácticas para Código Legible y Mantenible
  7. Dominando las plantillas de clase en C++: guía práctica
  8. Operadores en C++ explicados: Tipos, ejemplos y programas de muestra
  9. Sobrecarga de operadores en C++: Guía práctica con ejemplos de código
  10. Lenguaje de Programación C++: Visión General y Características Clave
  11. Dominando la Sobrecarga de Operadores en Python: Guía Práctica