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

Вниз

Копировать Объект   Найти похожие ветки 

 
Иван   (2002-05-14 01:24) [0]

Я Делфи не давно знаю, вопрос следующий, как в Делфи копировать объект в другой. В C++ этот вопрос решается просто - есть конструктор копирования, в Delphi же объект реально - указатель на объект и пр явном присваивании a:=b; приравниваются указатели, а хотелось бы получить копию. Как это сделатьв Delphi?


 
Almaz ©   (2002-05-14 02:17) [1]

Для объектов - потомков TPersistent (практически все стандартные объекты и компоненты Delphi) это реализуется с помошью метода Assign. Например:

var
A, B: TCanvas;

A := TCanvas.Create;
...
B := TCanvas.Create;
B.Assign(A); // Копируем A в B.


Удачи.


 
Лёша ©   (2002-05-14 02:20) [2]

Assign, AssignTo.


 
Кулюкин Олег ©   (2002-05-14 08:32) [3]

Только для своих собственных классов, Assign придется самому ручками реализовывать.


 
cpp ©   (2002-05-14 09:13) [4]

Обычные объекты нельзя.
Можно
1. через Assign. Но только потомки TPersistent
2. Можно Через поток TStream. У него есть метод WriteComponent ReadComponent. Но только потомки TComponent. И копируются только published свойства.



 
Иван   (2002-05-14 15:17) [5]

Спасибо, не очень красиво, но что делать :-(,
а есть способ пройти по всем свойствам объекта, и прокопировать их в другой в цикле?


 
Бурундук   (2002-05-14 17:08) [6]

Например, так:
(разумеется, только для published св-в)

procedure CopyPublishedProperties(Src, Dest: TObject);
var i: Integer;
Cls: TClass;

PropCnt: Integer;
PropList: PPropList;
PropInfo: PPropInfo;

function IsField(PropProc: Pointer): Boolean;
type ba = array[0..3]of Byte;
begin
Result := ba(PropProc)[3] > $FE;
end;

begin
if not Dest.InheritsFrom(Src.ClassType) then
raise Exception.CreateFmt("Cannot copy properties from %s to %s", [Src.ClassName, Dest.ClassName]);

PropCnt := GetTypeData(Src.ClassInfo)^.PropCount;
GetMem(PropList, PropCnt*SizeOf(Pointer));

try
GetPropInfos(Src.ClassInfo, PropList);

for i := 0 to PropCnt-1 do
begin
PropInfo := PropList^[i];
if (PropInfo^.Name <> "Name") then
begin
if PropInfo^.PropType^^.Kind = tkMethod then
SetMethodProp(Dest, PropInfo,
GetMethodProp(Src, PropInfo))
else if PropInfo^.PropType^^.Kind = tkClass then
begin
{
Cls := GetTypeData(PropInfo^.PropType^).ClassType;
if (not Cls.InheritsFrom(TComponent)) and
(Cls.InheritsFrom(TPersistent)) and
IsField(PropInfo^.SetProc)
}
if PropInfo^.Name = "Constraints"
then
// По непонятной причине свойство
// property Constraints: TSizeConstraints read FConstraints write FConstraints;
// производит запись прямо в поле, а не через Set-метод + Assign
// Поэтому приходится делать обходной маневр.
//
// Не исключено, что имеются подобные глюки и с другими (более редкими) св-вами.

TPersistent(GetObjectProp(Dest, PropInfo)).Assign
(TPersistent(GetObjectProp(Src, PropInfo)))
else
begin
SetObjectProp(Dest, PropInfo,
GetObjectProp(Src, PropInfo));
end;
end
else
SetPropValue(Dest, PropInfo^.Name, GetPropValue(Src, PropInfo^.Name));
end;
end;
finally
FreeMem(PropList, PropCnt*SizeOf(Pointer));
end;

// if (Src is TControl) then
// TControl(Dest).Parent := TControl(Src).Parent;
end;

PS Я не уверен, что учёл все тонкости, но вроде работает.



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

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

Наверх




Память: 0.48 MB
Время: 0.025 c
7-73414
Koks
2002-02-26 15:31
2002.05.23
КАК поставить файлу свое время...


4-73466
zondor
2002-03-25 15:03
2002.05.23
API - Cvjazj s drugimi Prilozenijami


1-73125
greenrul
2002-05-12 16:49
2002.05.23
Компонента Архивации


1-73190
Иван
2002-05-13 01:20
2002.05.23
Как продублировать


3-72995
Vygantas
2002-04-27 22:27
2002.05.23
Не получаетсья SQL запрос :((((