10

De acuerdo con las respuestas a this subproceso, operator= no se puede sobrecargar como una función no miembro. Entonces, por ejemplo, lo siguiente hace que el compilador se enoje mucho:Operador sobrecarga = como No miembro

class MyClass 
{ 
    // ... 
}; 

MyClass& operator=(MyClass& Left, MyClass& Right) 
{ 
    // ... 
} 

¿Por qué es esto? Tengo una clase de contenedor con getters y setters, por lo que una función miembro es innecesaria y rompería la encapsulación. Una de las respuestas al hilo antes mencionado dice que es para asegurarse de que el "valor L se reciba como su primer operando", pero no entiendo completamente lo que eso significa. ¿Podría alguien aclarar?

Además, son operator=, operator(), operator[] y operator-> casos "bicho raro" ...? ¿O debería implementar todos los operadores sobrecargados como funciones miembro ...? (Sé que es perfectamente legal hacer lo contrario, pero estoy buscando la mejor práctica.)

+1

Ver también este hilo http://stackoverflow.com/questions/3938036/rationale-of-enforcing-some-operators-to-be-members – UmmaGumma

+0

Creo que los getters/setters rompen el encapsulamiento más que un operador de asignación. Nota: Si no define uno, su clase ya tiene un operador de asignación. Intentalo. –

+0

Las funciones de miembro no rompen la encapsulación; ellos son parte de eso La preferencia de crear "funciones no miembro, no amigo" puede dar como resultado clases más simples, pero en el caso general, exponer todo lo necesario para implementar operator =() es más probable que debilite la encapsulación que hacer que operator =() sea un miembro. –

Respuesta

6

Si su clase no tiene un operador de asignación (como miembro), el compilador genera uno por defecto, al igual que genera un constructor de copia si no proporciona uno.

Por lo tanto, será "enojado" si intenta definir un operador de asignación no miembro más adelante. ¡Entonces habrá dos!

+0

La regla simplemente podría cambiarse para tratar de encontrar un no miembro uno primero. – GManNickG

+0

@GMan ¿Qué sucede si el operador que no es miembro está en otra unidad de traducción? ¿Una violación de ODR? –

+0

@Bo: suena razonable. – GManNickG

1

¿Por qué es esto?

A menos que se declara una, el compilador declara un operator= en su clase con la firma operator= (C&, C&) o operator= (C&, const C&).

Si se le permitió sobrecargar la tarea, la mayoría de los usos serían ambiguos.

entonces sería probable que ejercer presión para reglas adicionales a cualquiera:

  • pretender que no hay compilador declarada operator= si un usuario declara uno es visible, como si el no miembro operator= oculta el miembro de operator=
  • Haga que su asignación declarada por el usuario sea una mejor coincidencia durante la sobrecarga.

Ambas opciones complicarían las reglas que ya son extremadamente complicadas, agregando un caso especial solo para operator=.

Pocas personas quieren ir allí.

Y también no ha expuesto un uso legítimo para esta función.

O, any uso razonable en absoluto.

Las reglas de C++ solo se vuelven aún más complicadas cuando se puede mostrar un caso de uso razonable.