¿Qué significa “operador = debe ser un miembro no estática” significa?
-
22-08-2019 - |
Pregunta
Estoy en el proceso de creación de una lista ligada doble, y han sobrecargado el operador = para hacer iguales en la lista otra:
template<class T>
void operator=(const list<T>& lst)
{
clear();
copy(lst);
return;
}
pero me sale 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 la "}".
Solución
Exactamente lo que dice: sobrecargas de operadores deben ser funciones miembro. (Declarado dentro de la clase)
template<class T>
void list<T>::operator=(const list<T>& rhs)
{
...
}
Además, es probablemente una buena idea para devolver la LHS de = manera puede encadenar ella (como a = b = c
) - de modo que sea
list<T>& list<T>::operator=....
Otros consejos
Ponga ese operador dentro de la definición de clase. Debe ser un miembro operator=
porque es especial y que no iba a ganar algo escribiéndolo como no miembros de todos modos. Un operador no miembro tiene dos importantes ventajas principales:
- Las conversiones implícitas de la derecha y el lado izquierdo de la invocación del operador
- No hay necesidad de saber sobre elementos internos de la clase. La función puede ser realizado como no miembros no amigo.
Para list<T>
, tanto no es utilizable. Asignar a un resultado temporal de una conversión no tiene sentido, y void
tendrá acceso a los componentes internos en la mayoría de los casos. Además, un <=> especial se proporciona automáticamente por C ++ si no se proporciona uno (el llamado operador de copia de asignación). Por lo que es posible sobrecargar <=> como no miembros habría introducido una complejidad adicional para parecer no hay ganancia práctico, y por lo que no está permitido.
Así que cambiar su código para que se parezca a esto (esto supone la <=> es no un operador de copia de asignación, pero la asignación de un <=> a otra cosa. Esto no es claro por su pregunta):
class MyClass {
...
template<class T>
MyClass& operator=(const list<T>& lst)
{
clear();
copy(lst);
return *this;
}
...
};
Es bastante normal que un <=> devuelve una referencia a sí mismo de nuevo. Te recomiendo que se adhieren a esta práctica. Se verá familiar para los programadores y podría causar sorpresas si volvería <=> de repente.
Si se sobrecarga un operador como una función miembro, se debe utilizar esta plantilla:
class A {
A& operator=(const A& other) {
if (this != &other) {
...
}
return *this;
}
}
Hay tres cosas a tener en cuenta:
- Comprobar para la auto-asignación con el operador de asignación (como anteriormente);
- El argumento debe ser una referencia constante; y
- Devuelve el resultado de la operación como una referencia no const donde regresa * esto para permitir el encadenamiento de los operadores.
También puede sobrecargar un operador externo a la clase. Esto no es relevante para este ejemplo porque no se puede hacer con el operador de asignación, pero no vale de nada, porque en muchos casos es superior a funciones 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;
}
Éste devuelve una referencia constante por lo que no puede hacer esto:
(a + b) = c
A partir de C ++ estándar, "Operadores binarios":
"Un operador binario se efectuará bien por una función miembro no estática con un parámetro o por una función no miembro con dos parámetros"
Se quiere definir esto en una clase, como miembro, o lo convierten en un método estático (en cuyo caso se debe tomar dos parámetros (tanto para el lval y la rval).