Форум: "Основная";
Текущий архив: 2005.02.20;
Скачать: [xml.tar.bz2];
Внизпомогите сделать временную копию объекта Найти похожие ветки
← →
newid (2005-01-30 23:14) [0]может, вопрос совсем несерьезный, но не получается что-то...
нужно создать временную копию объекта ("резервную копию", из которой можно будет восстановить состояние исходного объекта при необходимости), при этом объект может быть экземпляром одного из нескольких наследников общего дедушки, т.е. точно класс объекта не знаем.
такое:
obj2 := obj1;
try
DoSome(obj1);
except
obj1 := obj2;
end;
само собой не катит, потому что с сылками работаем.
как вообще оперировать объектами в Object Pascal?
← →
P.N.P. © (2005-01-30 23:18) [1]Obj2.Assign(Obj1);
...
Obj1.Assign(Obj2);
← →
newid (2005-01-30 23:43) [2]
> [1] P.N.P.
ну... это если объекты -- экземпляры класса-наследника TPersistent.
и, кстати, у меня почему-то первая операция:
Obj2.Assign(Obj1);
дает такую ошибку:
---------------------------
map
---------------------------
Cannot assign a TSomeObject to a TSomeObject.
---------------------------
OK
---------------------------
вот мой код:
var
o1: TSomeObject;
o2: TSomeObject;
begin
o1 := TSomeObject.Create;
o2 := TSomeObject.Create;
o1.StringProp := "test1";
ShowMessage(o1.StringProp);
o2.Assign(o1); //Cannot assign a TSomeObject to a TSomeObject.
o1.StringProp := "test2";
ShowMessage(o1.StringProp);
o1.Assign(o2);
ShowMessage(o1.StringProp); //по задумке должно показать "test1"
o1.Free;
o2.Free;
end;
← →
jack128 © (2005-01-31 00:00) [3]newid (30.01.05 23:43) [2]
дает такую ошибку:
---------------------------
map
---------------------------
Cannot assign a TSomeObject to a TSomeObject.
потому что этот метод нужно реализововать самому.
← →
Юрий Зотов © (2005-01-31 01:49) [4]> как вообще оперировать объектами в Object Pascal?
Хороший вопрос. Но не знаю, как ответить. Писать книгу в online почему-то не готов.
← →
хм © (2005-01-31 02:19) [5]можно использовать CopyMemory, если в объекте нет указателей. Т.е, нужно много думать.
Но лучше не надо.(делать, а не думать :)
← →
Просто Джо © (2005-01-31 03:29) [6]Проще всего, неверное, унаследовать все классы от TPersistent. Далее, все свойства, которые нужно сохранять/восстанавливать сделать Pusblished. После этого использовать стандартные возможности стриминга для ТПерсистент.
Впрочем, в этом решении, как в остальных также много подводных камней. Но - лиха беда начало! :)
← →
Просто Джо © (2005-01-31 03:35) [7]
> [6] Просто Джо © (31.01.05 03:29)
Блин, заработался. Имелся в виду TComponent.
← →
newid (2005-01-31 07:22) [8]
> [6] Просто Джо © (31.01.05 03:29)
> Проще всего, неверное, унаследовать все классы от TPersistent.
можно. тут еще проблема: одно или несколько свойств объекта сами могут быть объектами. как такие свойства буду сохраняться?
мне кажется, нужно с памятью работать. что-то типа:
sz := o1.InstanceSize;
p2 := AllocMem(sz);
CopyMemory(p2, o1, sz);
DoSome(o1);
CopyMemory(o1, p2, sz);
FreeMem(p2, sz);
только это не работает. потому что неправильно написано. научил бы кто-нибудь правильно такое делать
← →
ЮЮ © (2005-01-31 07:58) [9]А не лучше вместо
obj2 := obj1;
try
DoSome(obj1);
except
obj1 := obj2;
end;
DoSome сделать виртуальным методом и уже в нем, реально зная, что можно "попортить", и делать необходимый "сохранения" и, собственно, откат в случае неудачи?
← →
jack128 © (2005-01-31 07:59) [10]newid (31.01.05 7:22) [8]
мне кажется, нужно с памятью работать. что-то типа:
Нет. Вот как раз в этом случае так делать не надо. см
хм © (31.01.05 2:19) [5] можно использовать CopyMemory, если в объекте нет указателей объекты - это тоже указатели.
← →
Erik1 © (2005-01-31 11:23) [11]Лучше логику ререработать, чем создовать механизм сохранения объектов. Небывает таких методов которые все даные сразу должны портить.
← →
pasha_golub © (2005-01-31 11:37) [12]А можно ситуацию подробней описать. Имею ввиду, зачем нужен резервный экземпляр? При каких таких раскладах? У меня даже мысли накакой нету.
← →
newid (2005-01-31 15:48) [13]
> [12] pasha_golub © (31.01.05 11:37)
> А можно ситуацию подробней описать
можно. резервный экземляр нужен, если пользователь работает с объектом, может менять его данные. а сам объект (его состояние) хранится постоянно где-то. ну начал юзер редактировать данные, вместо подтверждения изменений -- передумал, отменил изменения. объект (вернее его отображение) должен вернуться в прежнее состояние. можно, конечно, восстановить из места постоянного храниения, как это делается при инициализации, но ведь лишние операции ввода-вывода...
да кучу всяких подобных ситуаций можно придумать. мне кажется, что это вообще рабочая ситуация, с которой постоянно приходится сталкиваться.
вообще-то я полагал, что этот вопрос только от моего недостатка знаний, а получается, что он решается не так уж просто. или вообще не решается?...
← →
jack128 © (2005-01-31 16:02) [14]pasha_golub © (31.01.05 11:37) [12]
А можно ситуацию подробней описать. Имею ввиду, зачем нужен резервный экземпляр? При каких таких раскладах? У меня даже мысли накакой нету.
Ну, например, для реализации механизма транзакций..
newid (31.01.05 15:48) [13]
а получается, что он решается не так уж просто
В общем случае он не решается. В часных случаях возможны варианты. Например, для TPersistent можно сохранить состояние в поток, а потом, если нужно, восстановить его..
newid (31.01.05 15:48) [13]
как это делается при инициализации, но ведь лишние операции ввода-вывода...
Эти лишние операции существенно снижают производительность твоей программы?
← →
Gloomer © (2005-01-31 16:12) [15]>newid (30.01.05 23:43) [2]
Если я не ошибаюсь, то при определенииvar
o1: TSomeObject;
o2: TSomeObject;
о1 и о2 не относятся к одному типу. Попробуй лучшеvar o1, o2: TSomeObject;
← →
У (2005-01-31 16:15) [16]>Gloomer © (31.01.05 16:12) [15]
>Если я не ошибаюсь,
ты ошибаешься
← →
jack128 © (2005-01-31 16:36) [17]Gloomer © (31.01.05 16:12) [15]
о1 и о2 не относятся к одному типу.
ошибаешся.
А вот при таком
arr1: array of Integer;
arr2: array of Integer; действительно к разным типам
← →
newid (2005-01-31 16:38) [18]
> [14] jack128 © (31.01.05 16:02)
> Эти лишние операции существенно снижают производительность
> твоей программы?
нет, существенно не снижают. но ведь разумнее на "клиенте" эти вещи делать, согласись.
ладно. ткните меня носом в какие-нибудь исходники, где подобные механизмы реализованы
← →
GuAV © (2005-01-31 19:06) [19]
> ткните меня носом в какие-нибудь исходники, где
> подобные механизмы реализованы
TStream.WriteComponent;
← →
Просто Джо © (2005-01-31 19:12) [20]http://www.rsdn.ru/article/delphi/serialization.xml
← →
newid (2005-01-31 19:33) [21]
> [19] GuAV ©
> [20] Просто Джо ©
получается, сохранять в потоке -- единственный более-менее разумный подход...
← →
Просто Джо © (2005-02-01 03:07) [22]
> единственный более-менее разумный подход...
Мне лично он кажется наиболее "системным", универсальным что-ли.
← →
newid (2005-02-02 13:53) [23]да, кстати, а каких-нибудь готовых отлаженных библиотек на эту тему нет в природе?
← →
Amoeba © (2005-02-02 14:17) [24]
> newid (02.02.05 13:53) [23]
> да, кстати, а каких-нибудь готовых отлаженных библиотек
> на эту тему нет в природе?
IMHO таких нет.
← →
New11 (2005-02-02 14:25) [25]реализуй для своих классов метод Assign, как и было сказано. Самый внятный подход. А c использованием TypInfo получишь кучу глюков, тем паче что он не документирован.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2005.02.20;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.037 c