2015-12-27 4 views
7

Может кто-нибудь объяснить разницу между:Дельфи объект назначения против: =

(1.)

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

и

(2.)

newObj := oldObj; 

в 2. newObj и oldObj относятся к одному и тому же объекту?

Извините, если это был покрыт раньше, но это трудно найти :=

+1

Обратите внимание, что TObject не имеет метод Assign, только TPersistent делает.И описание TPersistent.Assign говорит о «похожих» объектах. Документы и контракты здесь немного размыты. – mjn

ответ

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

Предполагая, что Assign правильно реализована эта

  • создает новый экземпляр TMyObject (через Create)
  • хранит ссылку на этот экземпляр в переменной newObj (через оперу := tor)
  • Выполняет глубокую копию oldObj, делая newObj функционально точной копией oldObj (via Assign).

Конечный результат заключается в том, что у вас есть два совершенно разных экземпляра TMyObject, которые на данный момент являются точными копиями друг друга.


newObj := oldObj; 

Вышеуказанные просто копирует ссылку на oldObj и сохраняет его в переменной newObj. В этом случае у вас есть только один экземпляр TMyObject, и обе переменные newObj и oldObj указывают на тот же экземпляр. Если вы измените состояние этого объекта с помощью любой переменной, оба будут отражать эти изменения, поскольку оба они указывают на один и тот же базовый объект.

Это в отличие от приведенного выше примера, где у вас есть два отдельных объекта, состояние которых может расходиться, поскольку оба объекта изменяются независимо.


Концептуально, переменные объектов (классов), как правило, упоминаются как "ссылочных типов". Переменные этого типа по существу являются просто указателями (если это более знакомо). Назначение (:=) со ссылочными типами копирует только ссылку на объект, а не сам объект.

Единственным существенным исключением является тип string, который имеет множество свойств ссылочных типов, но управляется компилятором, а также ведет себя во многих отношениях как типы значений (изменение строки создает новую измененную копию, а не модификацию исходную строку, на которую можно ссылаться в другом месте).

Смотрите также: To copy from one object to another, can I assign the variables directly, or must I assign their properties individually?

+0

Строки не копируются при назначении, а счетчик внутренних экземпляров экземпляров; так же как и динамические массивы и (по умолчанию) интерфейсы. – kludg

+0

@ user246408 Хорошая точка. Я уточнил. –

+0

@ user246408, но стоит добавить: если строка с refcount> 1 каким-то образом изменена, она наконец-то скопирована, поэтому в конце мы получим две отдельные строки, поэтому она ведет себя так же, как если бы у нас было 2 независимых строки из начало. –