Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.10.18;
Скачать: CL | DM;

Вниз

Как в delphi получить копию экземпляра класса?   Найти похожие ветки 

 
sdsk ©   (2009-08-14 14:51) [0]

Давно не писал в Delphi. Напомните как это делается?


 
Amoeba ©   (2009-08-14 15:05) [1]

Если класс - потомок TPersistent - то с помощью метода Assign. Иначе - ручками.


 
Anatoly Podgoretsky ©   (2009-08-14 15:12) [2]

> sdsk  (14.08.2009 14:51:00)  [0]

Obj := TClass.Create


 
sdsk ©   (2009-08-14 15:19) [3]

Анатолий, внимательно вопрос прочтите. Я спрашивал как создать КОПИЮ ЭКЗЕМПЛЯРА класса, а не как создать экземпляр.


> Amoeba ©   (14.08.09 15:05) [1]
> Если класс - потомок TPersistent - то с помощью метода Assign.
>  Иначе - ручками.


Это довольно нестабильный подход. Assign определен в TPersistent как виртуальный. Каждый наследующий класс должен самостоятельно реализовывать нюансы по своему копированию. Если он это не делает, то мы получим только частичную копию.
Неужели в delphi нет способа скопировать экземпляр на низком уровне?


 
Palladin ©   (2009-08-14 15:24) [4]

А что такое "копия экземпляра" ?


 
Anatoly Podgoretsky ©   (2009-08-14 15:25) [5]

> sdsk  (14.08.2009 15:19:03)  [3]

А что именно скопировать то, ты видимо представляешь класс, как последовательность байтов, а это не так, поскольку есть ссылочные типы, при том возможно циклические. Лучший путь поэлементное копирование, но и оно не всегда достаточно.


 
Дмитрий Белькевич   (2009-08-14 15:26) [6]


> Неужели в delphi нет способа скопировать экземпляр на низком
> уровне?


Как ты себе это представляешь? В частности копирование динамических объектов/структур?


 
Palladin ©   (2009-08-14 15:29) [7]

Раз в пол года приходят вот такие вот человеческие "экземпляры давно не писавших в делфи" (то бишь вообще ничего не знающих) и начинают выступать. "Ну как так такого простого нет", сами понятия не имеют чего такое это самое "такое".


 
sdsk ©   (2009-08-14 15:39) [8]

>Palladin ©
Уважаемый, не зазнавайтесь. Ушел из delphi еще несколько лет назад на C#. В .NET данная задача решается с помощью механизма клонирования. Вот и возник вопрос есть ли что-либо подобное в Delphi.

> Anatoly Podgoretsky ©   (14.08.09 15:25) [5]
> > sdsk  (14.08.2009 15:19:03)  [3]
>
> А что именно скопировать то, ты видимо представляешь класс,
>  как последовательность байтов, а это не так, поскольку
> есть ссылочные типы, при том возможно циклические. Лучший
> путь поэлементное копирование, но и оно не всегда достаточно.
>


Сложности понимаю. Но и ссылочные типы также можно рекурсионно клонировать. В процессе этой операции множество нюансов, но все они технически решаемы.


 
Медвежонок Пятачок ©   (2009-08-14 15:40) [9]

ну закопируй например датасет если все так просто выглядит


 
Юрий Зотов ©   (2009-08-14 15:52) [10]

> sdsk ©   (14.08.09 15:39) [8]
> В .NET данная задача решается с помощью механизма клонирования.

И в Java тоже. Однако же, метод Clone пишет программист, разработчик класса - и как он этот метод реализовал, такую копию и получим. По умолчанию же выполняется неглубокое клонирование (что бывает опасно, потому что класс может содержать ссылки).

Аналогично и в Delphi. Неглубокое клонирование можно выполнить простым копированием памяти (что тоже опасно и по той же самой причине), а для глубокого служит метод Assign. Это аналог метода Clone, его тоже пишет разработчик класса и как он этот метод реализовал - такую копию и получим.

То есть, имеем практически полную аналогию. Чего, собственно, и следовало ожидать.


 
sdsk ©   (2009-08-14 15:55) [11]

Только есть одно отличие в .NET этот метод гарантирован интерфейсом ICloneable в Delphi же метод просто виртуальный. Соответственно нет никаких гарантий, что один из предков не нарушил последовательность клонирования. Но это правда не существенное отличие. В остальном алгоритм примерно схож


 
Юрий Зотов ©   (2009-08-14 16:02) [12]

> sdsk ©   (14.08.09 15:55) [11]

>  в .NET этот метод гарантирован интерфейсом ICloneable

Как и в Java.

> в Delphi же метод просто виртуальный. Соответственно нет никаких
> гарантий, что один из предков не нарушил последовательность
> клонирования.

Верно, таких гарантий нет. Но и в .Net, и в Java тоже нет гарантий что разработчик класса-предка написал метод Clone правильно. В итоге получим то же самое.


 
sdsk ©   (2009-08-14 16:05) [13]

согласен :)


 
Kolan ©   (2009-08-14 16:12) [14]

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

Как вариант можно написать класс-хелпер для TObject"а где и сделать соответствующую функцию.


 
sdsk ©   (2009-08-14 16:24) [15]


> Kolan ©   (14.08.09 16:12) [14]
> Все-таки иногда было бы удобно, чтобы метод, реализующий
> неглубокое копирование был уже в классе. Я, например, сходу
> не напишу копирование объекта путем копирования памяти,
> а вот вызвать метод, понимая что он делает мне под силу.
>
>
> Как вариант можно написать класс-хелпер для TObject"а где
> и сделать соответствующую функцию.


Я тоже подумывал над этим. Правда делфиские хелперы отстают от нетовских Extensions Methods. Могут быть сложности с кодингом. И будут неоднозначные ситуации, которые сложно решать на уровне предка. Но если предок возьмет на себя хотябы часть работы, это уже будет неплохо


 
Kolan ©   (2009-08-14 16:34) [16]

Я бы не стал, даже если бы это было возможно, делать простое копирование в предке и оставлять сложности на потомков. Потом хрен найдешь где что отвалилось.

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

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


 
Jonh   (2009-08-14 23:50) [17]


> Как вариант можно написать класс-хелпер для TObject"а где
> и сделать соответствующую функцию.


Пробовал делать хелпер для TObject, наткнулся на ошибки при компиляции. То есть все компилируется, но неправильно (при входе в тело метода хелпера теряются параметры), победить так и не сумели, пришлось от этой затеи отказаться


 
Kolan ©   (2009-08-15 00:06) [18]

Jonh, закинте пример, интересно проверить в разных версия Делфи.


 
Jonh   (2009-08-15 19:21) [19]


> Kolan ©   (15.08.09 00:06) [18]


модуль не сохранился, метод выглядел приблизительно так:
procedure TObjectHelper.LoadFromXML(const Node: IXMLNode; SomeEvent: TSomeEvent);

(попытка сделать реализацию сохранения\загрузки на основе RTTI)
Не исключено, что это уже исправили - проверьте, если не трудно (у меня под рукой нет Delphi), второй параметр - метод
при входе в тело LoadFromXML параметр Node указывал не на то, что передали


 
Kolan ©   (2009-08-15 23:18) [20]

Jonh, не обещаю, что попробую. Если бы вы дали такой пример, чтобы вставил-запустил-написал на форуме, то я бы проверил в Дельфи 2006-2007-2009



Страницы: 1 вся ветка

Текущий архив: 2009.10.18;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.012 c
3-1228320501
Tix
2008-12-03 19:08
2009.10.18
Многостраничная запись в QReport


2-1250853074
Начинающий1234
2009-08-21 15:11
2009.10.18
DrawItem (TListBox)


2-1250445565
alvonen
2009-08-16 21:59
2009.10.18
TOP_MOST окно перекрывается другими


2-1250318652
Константинов
2009-08-15 10:44
2009.10.18
работа с файлами *.adt и *.adi


1-1219636871
checkmate-maker
2008-08-25 08:01
2009.10.18
TRxRichEdit