TFirm = class// созданный класс
fid : Word;
firmname : String;
end;
procedure TForm.BtnClick(Sender: TObject);
Var
FIRM1, FIRM2 : TFIRM;
begin
FIRM1:=TFirm.Create;
FIRM2:=TFirm.Create;
FIRM1.fid:=1;
FIRM2.fid:=2;
FIRM1:=FIRM2; // здесь мне нужно скопировать значения всех свойств объекта FIRM2 в FIRM1(в данном случае fid, firmname), а получается что FIRM2 замещает FIRM1.
FIRM2.Free;
ShowMessage(IntToStr(FIRM1.fid)); // здесь вместо значения "2" выводится 4096end;
Здравствуйте, Chost,
Простым приравниванием вы просто говрите firm1 чтобы она брала данные из адреса памяти где находится firm2 (на пальцах) соответственно при удалении firm2 удаляются и данные, для приравнивания вы должны приравнять сами данные тоесть надо делать firm1.fid:=firm2.fid либо переопределить оператор = чтобы все это делалось автоматически. Извиняйте на паскале я не знаю как переопределить что либо....
-= ICQ:1887019 =- [Believe in the Matrix...] [...и Winamp молчит...]
Здравствуйте, Chost, Вы писали:
C> FIRM1:=FIRM2; // здесь мне нужно скопировать значения всех свойств объекта FIRM2 в FIRM1(в данном случае fid, firmname), а получается что FIRM2 замещает FIRM1.
Здравствуйте, Chost, Вы писали:
C>Доброго всем времени суток!
C>Подскажите как решить проблему, код ниже:
C> FIRM1:=FIRM2; // здесь мне нужно скопировать значения всех свойств объекта FIRM2 в FIRM1(в данном случае fid, firmname), а получается что FIRM2 замещает FIRM1.
Унаследуй свой класс от TPersistent и используй Assign:
TFirm = class(TPersistent)
fid : Word;
firmname : String;
public
procedure Assign (Source : TPersistent); override;
end;
...
procedure TFirm.Assign (Source : TPersistent); override;
begin
If Source is TFirm then
Begin
fid:=TFirm(Source).fid;
firmname:=TFirm(Source).firmname;
end
else inherited;
end;
И копируй классы вот так:
procedure TForm.BtnClick(Sender: TObject);
Var
FIRM1, FIRM2 : TFIRM;
begin
FIRM1:=TFirm.Create;
FIRM2:=TFirm.Create;
FIRM1.fid:=1;
FIRM2.fid:=2;
FIRM2.Assign(FIRM1);
FIRM2.Free;
FIRM1.Free;end;
Здравствуйте, Chost, Вы писали:
C>Проблема в том что свойств у меня не 2 а больше, также присутсутсвуют динамические массивы состоящие из объектов(см. ниже)
Я вроде как написал про функцию Assign которая будет методом этого класса и будет отвечать за присвоение. В ней можно определить какие свойства будут копироваться
Здравствуйте, AlexEagle, Вы писали:
S>>Унаследуй свой класс от TPersistent и используй Assign:
AE>Что-то я не понимать Зачем тогда унаследовать от TPersistent если все равно самому писать Assign
Ты бы хоть немножечко хелпик читать
Если у тебя в твоей модели данных всего один класс, то тогда действительно нефиг мудрить. Но такого никогда не бывает
Description
TPersistent encapsulates the behavior common to all objects that can be assigned to other objects, and that can read and write their properties to and from a form file (.xfm or .dfm file). For this purpose TPersistent introduces methods that can be overridden to:
Define the procedure for loading and storing unpublished data to a stream. Provide the means to assign values to properties. Provide the means to assign the contents of one object to another.
...
Кроме того, метод Assign пробегается по всей иерархии классов (ессно, если его реализовывать в соответствии с предложеной концепцией).
А это значит ты можешь делать Assign, когда типы не совпадают.
И еще, делая именно так ты увеличиваешь читабельность, юзабельность кода и поступаешь в соответствии с общепринятыми правилами. В результате при разработке ты делаешь меньше ошибок.
Здравствуйте, Spaider, Вы писали:
S>Если у тебя в твоей модели данных всего один класс, то тогда действительно нефиг мудрить. Но такого никогда не бывает
Не знаю, но мне кажется что все сказанное все равно реализуется простым написание своей процедуры Assign, хотя я конечно всега быд сторонником такого кода
Здравствуйте, Chost, Вы писали:
C>Спасибо всем!
C>Написал функцию Assign и всё заработало отлично!
C>P.S. Обидно что нет функции FIRM1:=FIRM2 %-)
Есть. Только ее тоже надо написать. Тоько я не знаю есть ли это в паскале... на с++ точно можно
Здравствуйте, Chost,
если унаследовать твои объекты от TObject и объявить их проперти как published, то можно воспользоваться RTTI:
procedure CopyObjectProps(Src, Dst: TObject);
var TypeData: PTypeData;
Props: PPropList;
PP: PPropInfo;
i: integer;
V: variant;
begin
TypeData:=GetTypeData(Src.ClassInfo);
if (TypeData = nil) or (TypeData^.PropCount = 0) then Exit;
GetMem(Props, TypeData^.PropCount * sizeof(Pointer));
try
GetPropInfos(Src.ClassInfo, Props);
for I := 0 to TypeData^.PropCount-1 do begin
PP:=GetPropInfo(Dst,Props^[I]^.Name);
if (PP=nil) then continue; // такого свойства у Dst нет
V:=GetPropValue(Src,Props^[I]^.Name,false);
SetPropValue(Dst,Props^[I]^.Name,V);
end;
finally
Freemem(Props);
end;
end;
Здравствуйте, konstbel, Вы писали:
K>Здравствуйте, Chost, K>если унаследовать твои объекты от TObject и объявить их проперти как published, то можно воспользоваться RTTI:
Вообще в VCL иногда применяется такой трюк:
компонент сериализуется в TMemoryStream, после чего десериализуется копия. Это чуть-чуть более компактный способ сделать то же самое, что ты предложил.
Нужно только отдавать себе отчет в том, что работоспособность метода опирается на предположение о полноте описания состояния объекта его сериализованным видом. Для компонентов это, как правило, справедливо. Именно из-за того, что разработчик просто обязан обеспечить адекватное представление в dfm. Для произвольного объекта это не всегда так.
... << RSDN@Home 1.1.4 beta 1 >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.