Leí que un operador sobrecargado declarado como función miembro es asimétrico porque solo puede tener un parámetro y el otro parámetro pasado automáticamente es el this
puntero. Entonces no existe un estándar para compararlos. Por otro lado, el operador sobrecargado declarado como a friend
es simétrico porque pasamos dos argumentos del mismo tipo y, por lo tanto, se pueden comparar.
Mi pregunta es que cuando todavía 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 la simétrica) ¿Por qué los algoritmos STL usan solo versiones simétricas?
Respuestas:
Si define la función sobrecargada de su operador como función miembro, el compilador traduce expresiones como
s1 + s2
ens1.operator+(s2)
. Eso 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, más bien digamos
double
. Entonces no puedes escribir así10.0 + s2
. Sin embargo, puede escribir la función miembro sobrecargada del operador para expresiones comos1 + 10.0
.Para resolver este problema de ordenación , definimos la función sobrecargada del operador como
friend
SI necesita acceder a losprivate
miembros. Hágalofriend
SOLO cuando necesite acceder a miembros privados. De lo contrario, simplemente conviértalo en una función no miembro no amiga para mejorar la encapsulación.Lea esto:
Un pequeño problema de orden en operandos
Cómo las funciones que no son miembros mejoran la encapsulación
fuente
friend
solo cuando necesite acceder a miembros privados ... y cuando no tenga / esté aburrido de escribira/b
.friend
es implementarlos en términos de operadores de asignación de operación (que casi con certeza serán miembros públicos). Por ejemplo, puede definirT T::operator+=(const T &rhs)
como miembro y luego definir no miembroT operator(T lhs, const T &rhs)
comoreturn lhs += rhs;
. La función no miembro debe definirse en el mismo espacio de nombres que la clase.No es necesariamente una distinción entre las
friend
sobrecargas del operador y las sobrecargas del operador de la función miembro, ya que lo es entre las sobrecargas del operador global y las sobrecargas del operador de la función miembro.Una razón para preferir una sobrecarga de operadores global es si desea permitir expresiones donde el tipo de clase aparece en el lado derecho de un operador binario. Por ejemplo:
Esto solo funciona si hay una sobrecarga de operador global para
Tenga en cuenta que la sobrecarga del operador global no tiene por qué ser necesariamente una
friend
función. Esto solo es necesario si necesita acceso a miembros privados deFoo
, pero no siempre es así.Independientemente, si
Foo
solo tuviera una sobrecarga de operador de función miembro, como:... entonces solo podríamos tener expresiones donde
Foo
aparezca una instancia a la izquierda del operador más.fuente