example - overload operator c++
¿Qué significa "operador=debe ser un miembro no estático"? (4)
De C ++ Standard, "operadores binarios":
"Un operador binario debe implementarse mediante una función miembro no estático con un parámetro o mediante una función no miembro con dos parámetros"
Quiere que defina esto en una clase, como miembro, o lo convierta en un método estático (en cuyo caso debería tomar dos parámetros (tanto para lval como para rval).
Estoy en el proceso de crear una lista de doble enlace, y he sobrecargado el operador = para hacer que la lista sea igual a otra:
template<class T>
void operator=(const list<T>& lst)
{
clear();
copy(lst);
return;
}
pero obtengo este error cuando intento compilar:
container_def.h(74) : error C2801: ''operator ='' must be a non-static member
Además, si ayuda, la línea 74 es la última línea de la definición, con el "}".
Exactamente lo que dice: las sobrecargas del operador con 1 parámetro deben ser funciones miembro. (declarado dentro de la clase)
template<class T>
void list<T>::operator=(const list<T>& rhs)
{
...
}
Además, probablemente sea una buena idea devolver el LHS de = para que pueda encadenarlo (como a = b = c
), por lo tanto, haga que sea una list<T>& list<T>::operator=....
Pon ese operador dentro de tu definición de clase. Debe ser un miembro porque operator=
es especial y de todos modos no ganarías algo escribiéndolo como no miembro. Un operador no miembro tiene dos beneficios principales importantes:
- Conversiones implícitas del lado derecho e izquierdo de la invocación del operador
- No es necesario saber acerca de los aspectos internos de la clase. La función se puede realizar como no miembro no amigo.
Para operator=
, ninguno es utilizable. Asignar a un resultado temporal de una conversión no tiene sentido, y operator=
necesitará acceso a internos en la mayoría de los casos. Además, C ++ proporciona automáticamente un operator=
especial operator=
si no proporciona uno (el llamado operador de copia de asignación). Posibilitar la sobrecarga del operator=
como no miembro habría introducido complejidad adicional para aparentemente ninguna ganancia práctica, y eso no está permitido.
Así que cambie su código para que se vea así (esto supone que el operator=
no es un operador de copia de asignación, sino que asigna desde una list<T>
a otra cosa. Esto no está claro en su pregunta):
class MyClass {
...
template<class T>
MyClass& operator=(const list<T>& lst)
{
clear();
copy(lst);
return *this;
}
...
};
Es bastante estándar que un operator=
devuelva una referencia a sí mismo nuevamente. Te recomiendo que te apegues a esa práctica. Les resultará familiar a los programadores y podría causar sorpresas si vuelve a quedar void
de repente.
Si sobrecarga un operador como una función miembro, debe usar esta plantilla:
class A {
A& operator=(const A& other) {
if (this != &other) {
...
}
return *this;
}
}
Tres cosas a tener en cuenta:
- Verifique la autoasignación con el operador de asignación (como se indicó anteriormente);
- El argumento debe ser una referencia constante; y
- Devuelve el resultado de la operación como una referencia no constante donde devuelve * esto para permitir el encadenamiento de operadores.
También puede sobrecargar un operador externo a la clase. Esto no es relevante para este ejemplo porque no puede hacerlo con el operador de asignación, pero vale la pena señalarlo porque en muchos casos es superior a las funciones de miembro. La forma típica es:
class A {
friend const A& operator+(const A& a, const A& b);
...
}
const A& operator+(const A& a, const A& b) {
A& ret = ...
return ret;
}
Este devuelve una referencia constante para que no pueda hacer esto:
(a + b) = c