2011-12-22 10 views

risposta

6

Restituisce un riferimento al membro privato.

In molti casi questo è auspicabile, ma occorre prestare attenzione.

IMO generalmente non è una buona idea restituire una copia di un oggetto interno che non è un tipo integrale, per motivi di prestazioni generali. Sì, lo so, l'ottimizzazione prematura non è buona, ma non si tratta di ottimizzazione, è solo una buona pratica di performance che consente al chiamante di determinare le implicazioni in termini di prestazioni; se vuole una copia, non può semplicemente dichiarare la variabile a cui la sta assegnando come riferimento.

Ci sono 2 regole generali che uso qui:

1) Se non si desidera che il chiamante sia in grado di modificare l'oggetto privato direttamente, dichiarare il valore di ritorno come riferimento const:

inline const string& GetLabel() const{ return m_Label; } 

2) Un chiamante non deve mai memorizzare il riferimento restituito da un metodo di classe, deve essere utilizzato solo localmente in cui l'oggetto padre è garantito nell'ambito.

Se per qualche motivo è necessario che i chiamanti siano in grado di memorizzare un riferimento agli oggetti interni, utilizzare invece i puntatori intelligenti.

11

La e commerciale non è prima del nome della funzione tanto quanto lo è dopo il tipo di ritorno. restituisce un riferimento a string.

L'implicazione di ciò è che un chiamante di questa funzione potrebbe modificare il valore di m_label tramite il riferimento. D'altra parte, evita di copiare la stringa. Si potrebbe desiderare il riferimento e la funzione di essere const, in questo modo:

inline const string& GetLabel() const 
{ 
    return m_Label; 
} 

meglio di entrambi i mondi. Si evita la copia, ma i chiamanti non possono modificare l'oggetto.

+0

In effetti, probabilmente si desidera _both_ le versioni const e non const. – ildjarn

+0

@ildjam Questo è solo parzialmente vero. Solitamente si desidera fornire solo la versione const, a meno che non si abbia un motivo per voler consentire ai chiamanti di modificare direttamente l'oggetto. Se fornisci la versione non const, dovresti anche fornire la versione const, in modo che tu possa ancora ottenere l'accesso di sola lettura dove hai un riferimento const all'oggetto padre. – Gerald

+1

@Gerald: Scusate, dovrei chiarire - volevo dire che, se volete la versione non-const che restituisce un riferimento, allora quasi certamente volete anche una versione const. – ildjarn

1

Sei corretto. È un riferimento al membro della stringa.

L'implicazione sarà che se un chiamante dovesse assegnare un valore o altrimenti modificare la stringa restituita che modificasse anche la variabile membro. Se questo non è l'intento, potresti voler restituire una copia in base al valore per evitare di rompere l'incapsulamento.

2

La restituzione di un riferimento indica che il codice chiamante può modificare il valore della variabile membro dopo il ritorno. È molto pericoloso, a meno che tu non intenda farlo.

Better è un riferimento const o restituisce in base al valore (senza &).

2

Una conseguenza è che se l'oggetto contenitore è destructed, il riferimento diventa valida:

Object* o = new Object; 
string& label = o->GetLabel(); 
delete o; 
// label becomes a dangling reference here. 

Un'altra conseguenza è che un chiamante può modificare la stringa. È possibile porvi rimedio restituendo un riferimento const.

Problemi correlati