Sovraccarico dell’operatore: funzione membro vs. funzione non membro?

Ho letto che un operatore sovraccarico ha dichiarato che la funzione membro è asimmetrica perché può avere solo un parametro e l’altro parametro passato automaticamente è il puntatore “this”. Quindi non esiste uno standard per confrontarli. D’altra parte, l’operatore sovraccaricato dichiarato come amico è simmetrico perché passiamo due argomenti dello stesso tipo e quindi, possono essere confrontati. La mia domanda è che quando posso ancora confrontare il valore di un puntatore a un riferimento, perché gli amici sono preferiti? (usando una versione asimmetrica dà gli stessi risultati di simmetrica) Perché gli algoritmi STL usano solo versioni simmetriche?

Se si definisce la funzione overload dell’operatore come funzione membro, il compilatore traduce espressioni come s1 + s2 in s1.operator+(s2) . Ciò significa che la funzione membro sovraccaricato dell’operatore viene richiamata sul primo operando. Ecco come funzionano le funzioni dei membri!

Ma cosa succede se il primo operando non è una class? C’è un grosso problema se vogliamo sovraccaricare un operatore in cui il primo operando non è un tipo di class, piuttosto double . Quindi non puoi scrivere come questo 10.0 + s2 . Tuttavia, è ansible scrivere la funzione membro sovraccaricato dell’operatore per espressioni come s1 + 10.0 .

Per risolvere questo problema di ordinamento , definiamo la funzione di overload dell’operatore come friend SE deve accedere private membri private . Rendilo friend SOLO quando ha bisogno di accedere ai membri privati. Altrimenti rendi semplicemente non-friend non-member la funzione per migliorare l’ incapsulamento!

 class Sample { public: Sample operator + (const Sample& op2); //works with s1 + s2 Sample operator + (double op2); //works with s1 + 10.0 //Make it `friend` only when it needs to access private members. //Otherwise simply make it **non-friend non-member** function. friend Sample operator + (double op1, const Sample& op2); //works with 10.0 + s2 } 

Leggi questo :
Un piccolo problema nell’ordinare gli operandi
In che modo le funzioni non membri migliorano l’incapsulamento

Non è necessariamente una distinzione tra sovraccarico dell’operatore friend e sovraccarico dell’operatore della funzione membro, come è tra i sovraccarichi dell’operatore globale e gli overload dell’operatore della funzione membro.

Un motivo per preferire un sovraccarico di un operatore globale è se si desidera consentire espressioni in cui il tipo di class appare sul lato destro di un operatore binario. Per esempio:

 Foo f = 100; int x = 10; cout << x + f; 

Funziona solo se c'è un sovraccarico dell'operatore globale per

Foo operator + (int x, const Foo & f);

Si noti che il sovraccarico dell'operatore globale non deve necessariamente essere una funzione di friend . Questo è necessario solo se ha bisogno di accedere ai membri privati ​​di Foo , ma non è sempre così.

Indipendentemente da ciò, se Foo aveva solo un sovraccarico dell'operatore di funzione membro, come:

 class Foo { ... Foo operator + (int x); ... }; 

... quindi potremmo avere solo espressioni in cui un'istanza di Foo appare a sinistra dell'operatore più.