2012-10-07 9 views
5

Continuando dal previous question vorrei chiedere perché la forma "amico" di addizione in un ++ operatore di sostituzione C è preferitoOverride dell'operatore C++: perché è preferibile l'amico?

Per riassumere:

per l'override dell'operatore Inoltre ci sono due modi per farlo :

int operator+(Object& e); 
friend int operator+(Object& left, Object& right); 

perché è che il secondo (amico) forma è preferita? Quali sono i vantaggi?

+1

Probabilmente meglio per citare i bit rilevanti dall'ultima domanda, quindi le persone non devono cliccarci sopra (e anche nel caso in cui la domanda scompaia) – nneonneo

risposta

5

La versione non membro (amico o altro) è preferibile perché può supportare conversioni implicite sul lato sinistro e destro dell'operatore.

Dato un tipo che è implicitamente convertibile in oggetto:

struct Widget 
{ 
    operator Object() const; 
}; 

la versione non-membro può essere chiamato solo se un'istanza di Widget appare sul lato sinistro:

Widget w; 
Object o; 

o + w; // can call Object::operator+(Object &) since left-hand side is Object 
w + o; // can only call operator+(Object &, Object &) 

In risposta al tuo commento:

Definendo la conversione op erator in Widget, stiamo notificando al compilatore che le istanze di Widget possono essere convertite automaticamente in istanze di Object.

Widget w; 
Object o = w; // conversion 

Nell'espressione o + w, il compilatore chiama Object::operator+(Object &) con un argomento generato convertendo w ad un Object. Quindi il risultato è lo stesso di scrivere o + w.operator Object().

Ma nell'espressione w + o, il compilatore cerca Widget::operator+ (che non esiste) o un membro non membro operator+(Widget, Object). Quest'ultimo può essere chiamato convertendo w in un Object come sopra.

+0

Non capisco perfettamente il codice struttura/oggetto dell'oggetto, puoi fornire un esempio semplice ed estremamente breve? –

2

La regola non è universale: la versione friend è preferibile quando si implementa un'operazione logicamente simmetrica che accetta due argomenti dello stesso tipo, ad esempio nel caso illustrato dal post.

Questa implementazione sottolinea il fatto che l'operazione è davvero simmetrica: non è un 'oggetto cio' che aggiunge Object e a se stesso - anzi, questo è un'aggiunta di lhs e rhs.

Nelle situazioni in cui l'operazione non è simmetrica - per esempio, quando si aggiunge un int ad un iteratore, si dovrebbe preferire il primo modo di operatori di applicazione, vale a dire

Object& operator+(int& offset); 
Problemi correlati