sencillos - sobrecarga de operadores unarios en c++
Sobrecarga del operador: ¿función miembro frente a función no miembro? (2)
No es necesariamente una distinción entre las sobrecargas del operador friend
y las sobrecargas del operador de la función miembro, ya que está entre las sobrecargas globales del operador y las sobrecargas del operador de la función miembro.
Una razón para preferir una sobrecarga de operador global es si desea permitir expresiones donde el tipo de clase aparece en el lado derecho de un operador binario. Por ejemplo:
Foo f = 100;
int x = 10;
cout << x + f;
Esto solo funciona si hay una sobrecarga de operador global para
Operador de Foo + (int x, const Foo & f);
Tenga en cuenta que la sobrecarga global del operador no necesariamente tiene que ser una función friend
. Esto solo es necesario si necesita acceder a miembros privados de Foo
, pero ese no es siempre el caso.
De todos modos, si Foo
solo tenía una sobrecarga de operador de función miembro, como:
class Foo
{
...
Foo operator + (int x);
...
};
... entonces solo podríamos tener expresiones donde aparezca una instancia de Foo
a la izquierda del operador más.
Leí que un operador sobrecargado declarado como función miembro es asimétrico porque puede tener solo un parámetro y el otro parámetro pasado automáticamente es el puntero ''this''. Entonces no existe un estándar para compararlos. Por otro lado, el operador sobrecargado declarado como amigo es simétrico porque pasamos dos argumentos del mismo tipo y, por lo tanto, se pueden comparar. Mi pregunta es que cuando aún puedo comparar el valor l de un puntero con una referencia, ¿por qué se prefieren los amigos? (El uso de una versión asimétrica da los mismos resultados que el simétrico) ¿Por qué los algoritmos STL usan solo versiones simétricas?
Si define la función sobrecargada de su operador como función miembro, entonces el compilador traduce expresiones como s1 + s2
en s1.operator+(s2)
. Esto significa que la función miembro sobrecargada del operador se invoca en el primer operando. ¡Así es como funcionan las funciones miembro!
Pero, ¿y si el primer operando no es una clase? Hay un problema importante si queremos sobrecargar un operador donde el primer operando no es un tipo de clase, sino double
. Entonces no puedes escribir así 10.0 + s2
. Sin embargo, puede escribir la función de miembro sobrecargado del operador para expresiones como s1 + 10.0
.
Para resolver este problema de ordenamiento , definimos la función sobrecargada del operador como friend
SI necesita acceder a miembros private
. Hazlo friend
SÓLO cuando necesite acceder a miembros privados. De lo contrario, simplemente haz que sea una función no miembro sin amigos para mejorar la encapsulación.
class Sample
{
public:
Sample operator + (const Sample& op2); //works with s1 + s2
Sample operator + (double op2); //works with s1 + 10.0
//Make it `friend` only when it needs to access private members.
//Otherwise simply make it **non-friend non-member** function.
friend Sample operator + (double op1, const Sample& op2); //works with 10.0 + s2
}
Lee esto :
Un pequeño problema de ordenar en operandos
Cómo las funciones no miembro mejoran la encapsulación