2010-05-19 8 views
9

¿Por qué no se permite sobrecargar "=" usando la función de amigo? He escrito un programa pequeño pero está dando un error.¿Por qué no podemos sobrecargar "=" usando la función amigo?

class comp 
{ 
int real; 
int imaginary; 
public: 
comp(){real=0; imaginary=0;} 
void show(){cout << "Real="<<real<<" Imaginary="<<imaginary<<endl;} 
void set(int i,int j){real=i;imaginary=j;} 
friend comp operator=(comp &op1,const comp &op2); 
}; 

comp operator=(comp &op1,const comp &op2) 
{ 
op1.imaginary=op2.imaginary; 
op1.real=op2.real; 
return op1; 
} 

int main() 
{ 
comp a,b; 
a.set(10,20); 
b=a; 
b.show(); 
return 0; 
} 

La compilación da el siguiente error: -

[[email protected] stackoverflow]# g++ prog4.cpp 
prog4.cpp:11: error: ‘comp operator=(comp&, const comp&)’ must be a nonstatic member function 
prog4.cpp:14: error: ‘comp operator=(comp&, const comp&)’ must be a nonstatic member function 
prog4.cpp: In function ‘int main()’: 
prog4.cpp:25: error: ambiguous overload for ‘operator=’ in ‘b = a’ 
prog4.cpp:4: note: candidates are: comp& comp::operator=(const comp&) 
prog4.cpp:14: note:     comp operator=(comp&, const comp&) 

Respuesta

7

El operador de asignación se requiere explícitamente para ser un operador miembro de la clase. Esa es una razón suficiente para que el compilador no compile su código. La asignación es una de las funciones de miembros especiales definidas en el estándar (como el constructor de copias) que generará el compilador si no proporciona las suyas propias.

A diferencia de otras operaciones que puede ser entendido como externos al operador de la parte izquierda, la asignación es una operación que está enlazado semánticamente a la izquierda: modificar este ejemplo para ser igual a la instancia lado derecho (por alguna definición de igual), por lo que tiene sentido tenerlo como una operación de la clase y no como una operación externa. Por otro lado, otros operadores como adición no están vinculados a una instancia particular: ¿es a+b una operación de a o b o ninguna de ellas? - a y b se utilizan en la operación, pero la operación actúa en el resultado valor que se devuelve.

Ese enfoque es realmente recomendable y se utiliza: definir operator+= (que se aplica a la instancia) como una función miembro, y luego implementar operator+ como una función gratuita que opera en el resultado:

struct example { 
    example& operator+=(const example& rhs); 
}; 
example operator+(const example& lhs, const example& rhs) { 
    example ret(lhs); 
    ret += rhs; 
    return ret; 
} 
// usually implemented as: 
// example operator+(example lhs, const example& rhs) { 
// return lhs += rhs; // note that lhs is actually a copy, not the real lhs 
//} 
+3

Sus razones no son válidas, porque 'operator =()' no está más vinculado a la instancia de destino que 'operator + =()', que * puede * definirse fuera de la clase, porque el compilador no interferirá e introducirá ambigüedad. –

+0

No dije que la semántica es lo que hace la distinción, o bien, como usted dice, todo 'operatorX =' tendría que ser funciones miembro. La razón por la cual no puede ser una función libre está en el primer párrafo: porque el estándar así lo dice. Supongo que no estaba claro, el inglés no es mi lengua materna. Solo quise decir que desde el punto de vista semántico tiene más sentido tener 'operatorX =' (incluyendo 'operator =') como funciones miembro, incluso si 'operatorX' generalmente se implementa mejor como una función gratuita. –

+4

Supongo que la pregunta es por qué el estándar dice que sí ;-) –

15

Porque si no se declara como un miembro de la clase compilador hará una para usted y que introducirá ambigüedad.

+0

¿Cuál es la firma para ese operador "=" sobrecargado que el compilador introduce automáticamente? – Ashish

+0

Igual que el suyo, pero el valor de retorno es una referencia. –

+1

Creo que es un 'TYPE & operator = (const TYPE &)' –

1

Asignación (=) operator es un operador especial que el constructor proporcionará a la clase cuando el programador no haya proporcionado (sobrecargado) como miembro de la clase (como el constructor de copia).
Cuando el programador está sobrecargando = operador usando la función amigo, dos = operaciones existirán:
1) el compilador está proporcionando = operador
2) el programador está proporcionando (sobrecarga) = operador por función amiga.
Entonces simplemente se creará ambigüedad y el compilador dará error. Su error de compilación

Cuestiones relacionadas