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