Domanda

Sono voler assicurarsi che ho capito pass-by-value vs passaggio per riferimento in modo corretto. In particolare, sto guardando le versioni prefisso / suffisso del operatore di incremento ++ per un oggetto.

Supponiamo di avere il seguente X classe:

class X{
private:
    int i;
public:
 X(){i=0;}
 X& operator ++ (){ ++i; return *this; } //prefix increment

 X operator ++ (int unused){ //postfix increment
  X ret(*this);
  i++;
  return ret;
 }

 operator int(){ return i; } //int cast
};

Prima di tutto, hanno ho implementato gli operatori prefisso / suffisso incremento correttamente?

In secondo luogo, come la memoria-efficiente è l'operatore postfix, rispetto al gestore del prefisso? In particolare il numero di copie di oggetti X vengono creati quando viene utilizzato ogni versione dell'operatore?

Una spiegazione di esattamente ciò che accade con ritorno per riferimento vs ritorno per valore potrebbe aiutarmi a capire.


Modifica: Per esempio, con il seguente codice ...

X a;
X b=a++;

... sono aeb ora alias?

È stato utile?

Soluzione

Questa è una corretta attuazione. E 'tipico che un operatore postfix sarà peggio sulle prestazioni perché si deve creare un'altra copia prima di fare l'incremento (e questo è il motivo per cui ho ottenuto l'abitudine di utilizzare sempre il prefisso a meno che non ho bisogno di qualcos'altro).

Con il ritorno per riferimento, si sta tornando un riferimento l-value per l'oggetto corrente. Il compilatore tipicamente implementare questa restituendo l'indirizzo dell'oggetto corrente. Ciò significa che restituisce l'oggetto è semplice come restituire un numero.

Tuttavia, con ritorno per valore, una copia deve essere fatto. Questo significa che non c'è più informazioni per copiare durante il ritorno (invece di un indirizzo), così come un costruttore di copia alla chiamata. Questo è dove il vostro colpo di prestazioni entra in gioco.

L'efficienza del tuo aspetto di implementazione in pari con le implementazioni tipiche.

EDIT: Per quanto riguarda il tuo addendum, no, non sono alias. È stato creato due oggetti separati. Quando ritorni per valore (e quando è stato creato un nuovo oggetto da dentro l'operatore postfix incremento) questo nuovo oggetto è collocato in una posizione di memoria distinta.

Tuttavia, nel seguente codice, a e b sono alias:

 int a = 0;
 int& b = ++a;

b è un indirizzo che fa riferimento a una.

Altri suggerimenti

E 'più idiomatico per chiamare il prefisso incremento dell'oggetto stesso in l'incremento postfix:

X operator++(int)
{
    X copy(*this);
    ++*this;         // call the prefix increment
    return copy;
}

La logica di incrementare un oggetto X viene così contenuta unicamente all'interno della versione prefisso.

I vostri operatori sono implementati correttamente.

l'operatore prefisso, sono fatte copie di X.

Nella operatore postfisso, una copia è fatto per ret, e potenzialmente un'altra copia è fatta al ritorno dalla funzione, ma tutti i compilatori si elide questa copia.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top