2012-10-07 6 views
5

Siguiendo con el previous question me gustaría preguntar por qué la forma "amigo" de la adición de una anulación operador de C++ se prefiereAnulación del operador C++: ¿por qué se prefiere a un amigo?

Para resumir:

para la anulación del operador Además, hay dos maneras de hacerlo :

int operator+(Object& e); 
friend int operator+(Object& left, Object& right); 

¿por qué es que el segundo formulario (amigo) es el preferido? ¿Cuáles son las ventajas?

+1

Probablemente es mejor citar los bits relevantes desde la última pregunta, para que la gente no tenga que hacer clic en ella (y también en caso de que la pregunta desaparezca) – nneonneo

Respuesta

5

Se prefiere la versión no miembro (amigo o no) porque puede admitir conversiones implícitas tanto en el lado izquierdo como derecho del operador.

Dado un tipo que es convertir implícitamente a Objeto:

struct Widget 
{ 
    operator Object() const; 
}; 

Sólo la versión no miembro puede ser llamado si una instancia de Widget aparece en el lado izquierdo:

Widget w; 
Object o; 

o + w; // can call Object::operator+(Object &) since left-hand side is Object 
w + o; // can only call operator+(Object &, Object &) 

En respuesta a tu comentario:

Al definir la conversión op erator en Widget, notificamos al compilador que las instancias de Widget se pueden convertir automáticamente a instancias de Object.

Widget w; 
Object o = w; // conversion 

En la expresión o + w, el compilador llama Object::operator+(Object &) con un argumento generada por la conversión a un wObject. El resultado es lo mismo que escribir o + w.operator Object().

Pero en la expresión w + o, el compilador busca Widget::operator+ (que no existe) o un no miembro operator+(Widget, Object). Este último puede invocarse convirtiendo w en Object como se indica arriba.

+0

No entiendo muy bien el código de la estructura widget/objeto, ¿puede proporcionar un ejemplo simple y extremadamente breve? –

2

La regla no es universal: se prefiere la versión friend cuando implementa una operación lógicamente simétrica que toma dos argumentos del mismo tipo, como el caso que muestra su publicación.

Esta aplicación pone de relieve el hecho de que la operación es realmente simétrica: no es un 'objeto de este' que añade Object e a sí mismo - más bien, eso es una adición de lhs y rhs.

En situaciones en las que la operación no es simétrico - por ejemplo, cuando se agrega un int a un repetidor, se debe preferir la primera forma de operadores de ejecución, es decir,

Object& operator+(int& offset); 
Cuestiones relacionadas