La cuestión es que cuando quieras sobrecargar un operador tienes que tener clara una (dos) cosa(s):
1. Si el primer operando (el que está más a la izquierda) es de la clase o no.
1.1 Si no es de la clase sobre la que estás trabajando el operador no puede ser un miembro de la clase:
class MiEntero
{
public:
//...
private:
int x;
};
/* si queremos sumar un entero y un elemento de mi clase, como el entero no es un objeto de mi clase, tendré que declarar el operador suma fuera de la clase.
La suma es un operador binario y el elemento más a la izquierda es de clase entero, luego a la hora de sobrecargarlo la lista de parámetros tendrá dos valores,
un entero y un elemento de la clase y devolveré un elemento de mi clase, que engloba a los enteros y así mantengo las reglas de promoción:*/
//...
MiEntero operator+ (int op1, MiEntero &op2) //pasamos una referencia al objeto de la clase para evitar sobrecargar la pila
{
//me las arreglo para generar un elemento MiEntero que almacene el valor suma y devuelvo este objeto
}
/*a la hora de llamar al operador, x+y con x entero e y un objeto de mi clase, se genera una llamada operator+(x,y)*/
1.2 Si el objeto más a la izquierda es de la clase tenemos dos opciones:
1.2.1. Declarar el operador fuera de la clase con una lista de dos parámetros, ambos de la clase con la que estamos trabajando (igual que antes).
1.2.2. Declarar el operador como miembro de la clase, con un solo parámetro de la clase. La llamada a operador suma, x + y con los dos operandos objetos de mi clase, generará una llamada x.operator+(y), así que para hacer referencia a x dentro de la definición del operador tendrás que utilizar el puntero this:
class MiEntero
{
public:
//...
MiEntero operator+(MiEntero &op2); //como la lista de parámetros es distinta a la la del operador exterior no incumplo las reglas de sobrecarga de funciones/operadores
private:
int x;
};
MiEntero MiEntero::operator+(MiEntero &op2)
{
MiEntero res;
res.x = this->x + op2.x;
return res;
}
/* si queremos sumar un entero y un elemento de mi clase, como el entero no es un objeto de mi clase, tendré que declarar el operador suma fuera de la clase.
La suma es un operador binario y el elemento más a la izquierda es de clase entero, luego a la hora de sobrecargarlo la lista de parámetros tendrá dos valores,
un entero y un elemento de la clase y devolveré un elemento de mi clase, que engloba a los enteros y así mantengo las reglas de promoción:*/
//...
MiEntero& operator+ (int op1, MiEntero &op2) //pasamos una referencia al objeto de la clase para evitar sobrecargar la pila
{
//me las arreglo para generar un elemento MiEntero que almacene el valor suma y devuelvo este objeto
}
La segunda opción sería declarar los operadores exteriores a la clase como friend para poder tener un acceso inmediato a sus miembros privados.
¡Saludos!