|
#1
|
||||
|
||||
Проблема с record
Есть следующий код (примерный, чтобы долго не вникать):
Код:
type Record1 = record var1:string; var2:string; var3:string; end; Records1 = array of Record1; Class1 = class public ArrOfRecord1:Records1; Var1:string; Var2:string; end; *** Procedure proc1; var C1:Class1; C2:Class1 begin c1:=Class1.Create; c2:=Class1.Create; setlength(C1.ArrOfRecord1, 2); C2:=C1; C1.ArrOfRecord1[0].var1:='qwe'; C1.ArrOfRecord1[0].var2:='asd'; C1.ArrOfRecord1[0].var3:='zxc'; C1.ArrOfRecord1[1].var1:='123'; C1.ArrOfRecord1[1].var2:='345'; C1.ArrOfRecord1[1].var3:='567'; ShowMessage(C2.ArrOfRecord1[1].var3); end; Проблема в том, что когда я создаю 2 экземпляра класса Class1 и делаю присвоение в proc1, его набор ArrOfRecord1 ссылается на один и тот же Records1. То есть ShowMessage(C2.ArrOfRecord1[1].var3) выводит '567'. Как изменить код, чтобы это исправить? |
#2
|
|||
|
|||
Цитата:
исправлять можно по всякому, один из вариантов вроде такого: Код:
uses contnrs; Record = class ... constructor (v1,v2,v3) end MyClass = class(TObjectList) // ему размерность не надо фиксировать, сколько добавишь столько и будет ... >woweook< Последний раз редактировалось Pyro, 28.11.2012 в 07:49. |
#3
|
||||
|
||||
Так ты ж сам присвоил:
Код:
C2:=C1; Попробуй, для разнообразия, сделать Код:
c1.free Некоторые программисты настолько ленивы, что сразу пишут рабочий код. Если вас наказали ни за что - радуйтесь: вы ни в чем не виноваты. |
Этот пользователь сказал Спасибо Aristarh Dark за это полезное сообщение: | ||
morebeauty (28.11.2012)
|
#4
|
||||
|
||||
Я примерно так же и подумал.
Подскажите тогда универсальный выход, как все переменные класса C1 присвоить переменным класса C2, чтобы не вручную присваивать их, а по циклу (переменных на самом деле много и их количество может изменяться). |
#5
|
||||
|
||||
Есть такой класс, TPersistent называется. Его наследники получают от него один замечательный метод Assign. Так вот этот метод позволяет и позволяет создавать копии полей класса.
Некоторые программисты настолько ленивы, что сразу пишут рабочий код. Если вас наказали ни за что - радуйтесь: вы ни в чем не виноваты. |
Этот пользователь сказал Спасибо Aristarh Dark за это полезное сообщение: | ||
morebeauty (28.11.2012)
|
#6
|
||||
|
||||
Код:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) btn1: TButton; procedure btn1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; Record1 = record var1:string; var2:string; var3:string; end; Records1 = array of Record1; Class1 = class(TPersistent) public ArrOfRecord1:Records1; Var1:string; Var2:string; end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.btn1Click(Sender: TObject); var C1:Class1; C2:Class1; begin c1:=Class1.Create; c2:=Class1.Create; setlength(C1.ArrOfRecord1, 2); C1.Assign(C2); C1.ArrOfRecord1[0].var1:='qwe'; C1.ArrOfRecord1[0].var2:='asd'; C1.ArrOfRecord1[0].var3:='zxc'; C1.ArrOfRecord1[1].var1:='123'; C1.ArrOfRecord1[1].var2:='345'; C1.ArrOfRecord1[1].var3:='567'; ShowMessage(C2.ArrOfRecord1[1].var3); end; end. project project1.exe raised exception class EConvertError with message 'Cannot assign a Class1 to a Class1'. Process stoped. |
#7
|
||||
|
||||
для того, чтобы воспользоваться методом Assign класса TPersistent, его нужно override:
Код:
type MyRec = record s1: String; s2: String; end; MyRecs = array of MyRec; TMyClass = class(TPersistent) public Recs: MyRecs; v1: String; v2: String; procedure Assign(Source: TPersistent); override; end; procedure TMyClass.Assign(Source: TPersistent); var i: Integer; begin v1:=TMyClass(Source).v1; v2:=TMyClass(Source).v2; SetLength(Recs, Length(TMyClass(Source).Recs)); for i:=0 to Length(TMyClass(Source).Recs)-1 do begin Recs[i].s1:=TMyClass(Source).Recs[i].s1; Recs[i].s2:=TMyClass(Source).Recs[i].s2; end; end; Код:
TForm1 = class(TForm) Memo1: TMemo; procedure FormCreate(Sender: TObject); procedure TForm1.FormCreate(Sender: TObject); var c1, c2: TMyClass; begin c1:=TMyClass.Create; c2:=TMyClass.Create; c1.v1:='123'; c1.v2:='abc'; SetLength(c1.Recs, 2); c1.Recs[0].s1:='hello'; c1.Recs[0].s2:='world'; c1.Recs[1].s1:='bill'; c1.Recs[1].s2:='gates'; c2.Assign(c1); Memo1.Lines.Add(c1.v1); Memo1.Lines.Add(c1.v2); Memo1.Lines.Add(c2.v1); Memo1.Lines.Add(c2.v2); Memo1.Lines.Add(c1.Recs[0].s1); Memo1.Lines.Add(c1.Recs[0].s2); Memo1.Lines.Add(c1.Recs[1].s1); Memo1.Lines.Add(c1.Recs[1].s2); Memo1.Lines.Add(c2.Recs[0].s1); Memo1.Lines.Add(c2.Recs[0].s2); Memo1.Lines.Add(c2.Recs[1].s1); Memo1.Lines.Add(c2.Recs[1].s2); end; Пишу программы за еду. __________________ |
Этот пользователь сказал Спасибо NumLock за это полезное сообщение: | ||
morebeauty (28.11.2012)
|
#8
|
||||
|
||||
А ну то есть мне так и так придется все переназначать вручную. Это проблематично. Есть ли способ скопировать область памяти занятую классом C1 в свободную область и указать С2 на эту область?
|
#9
|
||||
|
||||
Так ты 1 раз напишешь, а потом будешь использовать в любом месте. Плюс в наследниках будешь использовать метод предка и допишешь копирование только новых полей.
Некоторые программисты настолько ленивы, что сразу пишут рабочий код. Если вас наказали ни за что - радуйтесь: вы ни в чем не виноваты. |
#10
|
||||
|
||||
А что вы можете сказать про запись и чтение из стримов? Я, может, не достаточно понял что это такое, это подойдет для моего случая?
http://www.delphisources.ru/pages/fa...to_thread.html http://forum.vingrad.ru/topic-94245/view-all.html |
#11
|
||||
|
||||
для published подойдет, но не для record
Пишу программы за еду. __________________ |
Этот пользователь сказал Спасибо NumLock за это полезное сообщение: | ||
morebeauty (28.11.2012)
|
#12
|
||||
|
||||
Всем спасибо. Сделал в классе процедуру AssignOptions а в ней уже поименно перекинул все переменные.
|