2015-12-27 28 views
7

Qualcuno potrebbe spiegare la differenza tra:Delphi oggetto assegnare vs: =

(1.)

newObj := TMyObject.Create; 
newObj.Assign(oldObj); 

e

(2.)

newObj := oldObj; 

a 2. newObj e oldObj si riferiscono allo stesso singolo oggetto?

Scusate se questo è stato coperto prima, ma è è difficile per cercare :=

+1

noti che TObject non ha un metodo Assegna, solo TPersistent fa.E la descrizione di TPersistent.Assign parla di oggetti "simili". Documenti e contratti sono un po 'confusi qui. – mjn

risposta

5
newObj := TMyObject.Create; 
newObj.Assign(oldObj); 

Supponendo che Assign corretta applicazione, questo

  • crea una nuova istanza di TMyObject (via Create)
  • memorizza un riferimento a tale istanza nella variabile newObj (tramite l'opera tor)
  • Esegue una copia profonda di oldObj, rendendo newObj una copia funzionalmente esatta di oldObj (via Assign).

Il risultato finale qui è che ci sono due istanze completamente separate di TMyObject che sono, a questo punto, copie esatte l'una dell'altra.


newObj := oldObj; 

I copia semplicemente sopra un riferimento per oldObj e lo memorizza nella variabile newObj. In questo caso hai ancora solo un'istanza di TMyObject e entrambe le variabili newObj e oldObj puntano alla stessa istanza. Se modifichi lo stato di quell'oggetto utilizzando una variabile, entrambi rifletteranno tali cambiamenti poiché entrambi puntano allo stesso oggetto sottostante.

Questo è in contrasto con l'esempio precedente in cui si dispone di due oggetti separati il ​​cui stato può divergere in quanto entrambi gli oggetti vengono modificati in modo indipendente.


Concettualmente, le variabili di oggetti (classi) sono generalmente chiamati "tipi di riferimento". Le variabili di questo tipo sono essenzialmente solo puntatori (se questo è più familiare). L'assegnazione (:=) con tipi di riferimento copia solo il riferimento all'oggetto, non l'oggetto stesso.

L'unica eccezione sostanziale a questo sono i tipi string, che hanno molte proprietà dei tipi di riferimento, ma sono gestiti dal compilatore per comportarsi in molti modi anche come tipi di valore (la modifica di una stringa produce una nuova copia modificata invece di modificare il stringa originale a cui è possibile fare riferimento altrove).

Vedi anche: To copy from one object to another, can I assign the variables directly, or must I assign their properties individually?

+0

Le stringhe non vengono copiate nell'assegnazione, ma incrementano il contatore di riferimento dell'istanza interna; come gli array dinamici e le interfacce (di default). – kludg

+0

@ user246408 Buon punto. Ho chiarito –

+0

@ user246408 ma vale la pena di aggiungere: se la stringa con refcount> 1 viene modificata in qualche modo, alla fine viene copiata, quindi alla fine otteniamo 2 stringhe separate, quindi si comporta come se avessimo 2 stringhe indipendenti dal inizio. –