Delphi

 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me



Go Back   Tutorialized ForumsDesktop ProgrammingDelphi

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Tutorialized Forums Sponsor:
  #1  
Old May 22nd, 2008, 10:18 AM
hannesbez hannesbez is offline
Registered User
Tutorialized Newbie (0 - 499 posts)
 
Join Date: May 2008
Location: Johannesburg
Posts: 9 hannesbez User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 20 m 13 sec
Reputation Power: 0
Send a message via Skype to hannesbez
Dynamic Array of Objects

I am defining a Student class
Student = class
Name, Surname : string;
etc.
Student = TStudent.Create;
arrStudent : array of TStudent;

As I complete each Student record, I want to add it to a dynamic array like
SetLength(arrStudent, n+1];
arrStudent[n] := Student;
PROBLEM: It works, except that each element of the array is filled with the last Student record, i.e. the same name, the same surname, etc for every element in the array!
Is it possible to use an array like this, if so, how?
Thank you for any help out there.
HB

Reply With Quote
  #2  
Old May 22nd, 2008, 10:33 AM
UseShots UseShots is offline
Registered User
Tutorialized Newbie (0 - 499 posts)
 
Join Date: May 2008
Posts: 11 UseShots User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 h 36 m 22 sec
Reputation Power: 0
Hi,

Did you consider using TList or TObjectList instead? Much more convenient than dynamic arrays.

Reply With Quote
  #3  
Old May 22nd, 2008, 10:44 AM
hannesbez hannesbez is offline
Registered User
Tutorialized Newbie (0 - 499 posts)
 
Join Date: May 2008
Location: Johannesburg
Posts: 9 hannesbez User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 20 m 13 sec
Reputation Power: 0
Send a message via Skype to hannesbez
TObjectList

[QUOTE=UseShots]Hi,

Must admit, I have not. We are somewhat bound by what we may teach (try to) to students.

Reply With Quote
  #4  
Old May 22nd, 2008, 10:50 AM
UseShots UseShots is offline
Registered User
Tutorialized Newbie (0 - 499 posts)
 
Join Date: May 2008
Posts: 11 UseShots User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 h 36 m 22 sec
Reputation Power: 0
I didn't use dynamic arrays for a long time, but it looks like a bug in the code where you populate the array.

If you provide me with the code snippet, I would play with it

Reply With Quote
  #5  
Old May 22nd, 2008, 11:11 AM
UseShots UseShots is offline
Registered User
Tutorialized Newbie (0 - 499 posts)
 
Join Date: May 2008
Posts: 11 UseShots User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 h 36 m 22 sec
Reputation Power: 0
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Here is my example that works well:

delphi Code:
Original - delphi Code
  1.  
  2. unit Unit1;
  3.  
  4. interface
  5.  
  6. uses
  7.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  8.   Dialogs, StdCtrls;
  9.  
  10. type
  11.  
  12.   TStudent = class
  13.     Name : String;
  14.   end;
  15.  
  16.   TForm1 = class(TForm)
  17.     Button1: TButton;
  18.     Edit1: TEdit;
  19.     Memo1: TMemo;
  20.     Button2: TButton;
  21.     procedure Button1Click(Sender: TObject);
  22.     procedure FormCreate(Sender: TObject);
  23.     procedure Button2Click(Sender: TObject);
  24.     procedure FormDestroy(Sender: TObject);
  25.   private
  26.     FArrStudent : array of TStudent;
  27.   public
  28.     { Public declarations }
  29.   end;
  30.  
  31. var
  32.   Form1: TForm1;
  33.  
  34. implementation
  35.  
  36. {$R *.dfm}
  37.  
  38. procedure TForm1.Button1Click(Sender: TObject);
  39. var
  40.   student : TStudent;
  41.   curLent : Integer;
  42. begin
  43.   student := TStudent.Create;
  44.   student.Name := Edit1.Text;
  45.   SetLength(FArrStudent, Length(FArrStudent)+1);
  46.   FArrStudent[ High(FArrStudent) ] := student;
  47. end;
  48.  
  49. procedure TForm1.FormCreate(Sender: TObject);
  50. begin
  51.   SetLength(FArrStudent, 0);
  52. end;
  53.  
  54. procedure TForm1.Button2Click(Sender: TObject);
  55. var
  56.   i : Integer;
  57. begin
  58.   for i:= Low(FArrStudent) to High(FArrStudent) do
  59.   begin
  60.     Memo1.Lines.Add( FArrStudent[i].Name );
  61.   end;
  62. end;
  63.  
  64. procedure TForm1.FormDestroy(Sender: TObject);
  65. var
  66.   i : Integer;
  67. begin
  68.   for i:= Low(FArrStudent) to High(FArrStudent) do
  69.   begin
  70.     FArrStudent[i].Free;
  71.   end;
  72.   SetLength(FArrStudent, 0);
  73. end;
  74.  
  75. end.

Reply With Quote
  #6  
Old May 22nd, 2008, 11:53 AM
hannesbez hannesbez is offline
Registered User
Tutorialized Newbie (0 - 499 posts)
 
Join Date: May 2008
Location: Johannesburg
Posts: 9 hannesbez User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 20 m 13 sec
Reputation Power: 0
Send a message via Skype to hannesbez
Dynamic array of Objects

Many thanks. Here is the code (trust this is the way to send it to you):

implementation

{$R *.dfm}

type
TStudent = class(TObject)
Name : string;
Surname : string;
Gender : boolean;
Age : integer;
end;

var
Student : TStudent; //declare it as global
arrStudent : array of TStudent;


procedure TForm1.FormCreate(Sender: TObject);
begin
Student := TStudent.Create;

with Student do
begin
Name := 'John';
Surname := 'Anderson';
Gender := True;
Age := 15;
end;
SetLength(arrStudent, 1);
arrStudent[0] := Student;

with Student do
begin
Name := 'Sam';
Surname := 'Peterson';
Gender := True;
Age := 17;
end;
SetLength(arrStudent, 2);
arrStudent[1] := Student;

with Student do
begin
Name := 'Dineo';
Surname := 'Peters';
Gender := False;
Age := 16;
end;
SetLength(arrStudent, 3);
arrStudent[2] := Student;

with Student do
begin
Name := 'Melissa';
Surname := 'Mamelo';
Gender := False;
Age := 17;
end;
SetLength(arrStudent, 4);
arrStudent[3] := Student;

with Student do
begin
Name := 'Nicholas';
Surname := 'Moropodi';
Gender := True;
Age := 16;
end;
SetLength(arrStudent, 5);
arrStudent[4] := Student; //all elements equal this last Student!

end;

Reply With Quote
  #7  
Old May 22nd, 2008, 12:40 PM
hannesbez hannesbez is offline
Registered User
Tutorialized Newbie (0 - 499 posts)
 
Join Date: May 2008
Location: Johannesburg
Posts: 9 hannesbez User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 20 m 13 sec
Reputation Power: 0
Send a message via Skype to hannesbez
Adjusted my code as per your suggestion - same result. All records are exactly the same! get the idea that I'm not seeing the wood for the trees.

Reply With Quote
  #8  
Old May 22nd, 2008, 12:49 PM
hannesbez hannesbez is offline
Registered User
Tutorialized Newbie (0 - 499 posts)
 
Join Date: May 2008
Location: Johannesburg
Posts: 9 hannesbez User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 20 m 13 sec
Reputation Power: 0
Send a message via Skype to hannesbez
Forgot to mention, I tried TObjectList - with the same result.

Reply With Quote
  #9  
Old May 22nd, 2008, 01:57 PM
UseShots UseShots is offline
Registered User
Tutorialized Newbie (0 - 499 posts)
 
Join Date: May 2008
Posts: 11 UseShots User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 h 36 m 22 sec
Reputation Power: 0
Hey!

What you do here is insert the same object into different position of the array. You have only one TStudent object. No wonder you get the same result for every position.

You need to create new objects for every position. And don't forget to destroy those object when they are no longer needed. (TObjectList does it automatically)

Reply With Quote
  #10  
Old May 22nd, 2008, 03:13 PM
hannesbez hannesbez is offline
Registered User
Tutorialized Newbie (0 - 499 posts)
 
Join Date: May 2008
Location: Johannesburg
Posts: 9 hannesbez User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 20 m 13 sec
Reputation Power: 0
Send a message via Skype to hannesbez
I'm sorely testing your patience but - I have no idea how to do that. I have tried arrStudent[n].Create to no avail, also destroying Student after every addition to the array and recreating Student before the next loop, with equally disastrous effects. Help?

Reply With Quote
  #11  
Old May 22nd, 2008, 03:41 PM
UseShots UseShots is offline
Registered User
Tutorialized Newbie (0 - 499 posts)
 
Join Date: May 2008
Posts: 11 UseShots User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 h 36 m 22 sec
Reputation Power: 0
student := TStudent.Create;
... //assign values here
arrStudent[1] := student;

student := TStudent.Create;
... //assign values here
arrStudent[2] := student;

...

student := TStudent.Create;
... //assign values here
arrStudent[n] := student;
-------------------------------

When you need to free memory do the following

delphi Code:
Original - delphi Code
  1.  
  2. var
  3.   i : Integer;
  4. begin
  5.   for i:=Low(arrStudent) to High(arrStudent) do
  6.     arrStudent[i].Free;
  7.   SetLength(arrStudent, 0);
  8. end;


if you decided to use TObjectList, just say objectList.Free;

Reply With Quote
  #12  
Old May 23rd, 2008, 12:02 AM
hannesbez hannesbez is offline
Registered User
Tutorialized Newbie (0 - 499 posts)
 
Join Date: May 2008
Location: Johannesburg
Posts: 9 hannesbez User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 20 m 13 sec
Reputation Power: 0
Send a message via Skype to hannesbez
If you were closer I'd give you a great bear hug!!! I was creating the Student as you say but - freeing it after every add to the array - not allowed. Next step now is to get to grips with the TObjectList; is it really that much better approach than an array?

Reply With Quote
  #13  
Old May 23rd, 2008, 12:50 AM
UseShots UseShots is offline
Registered User
Tutorialized Newbie (0 - 499 posts)
 
Join Date: May 2008
Posts: 11 UseShots User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 h 36 m 22 sec
Reputation Power: 0
With TObjectList you don't have to warry about the size of the list.
The only (small) drawback is you have to typecast list items as they are TObject by default.

Or you can create your own TStudentList that returns TStudent.

delphi Code:
Original - delphi Code
  1.  
  2. type
  3.   TStudentList = class(TObjectList)
  4.   protected
  5.     procedure SetStudent(I: Integer; AStudent: TStudent);
  6.     function GetStudent(I: Integer): TStudent;
  7.   public
  8.     property Students[I: Integer]: TStudent read GetStudent write SetStudent;
  9.   end;
  10.  
  11.   TForm1 = class(TForm)
  12.     Button1: TButton;
  13.     Edit1: TEdit;
  14.     Memo1: TMemo;
  15.     Button2: TButton;
  16.     procedure Button1Click(Sender: TObject);
  17.     procedure FormCreate(Sender: TObject);
  18.     procedure Button2Click(Sender: TObject);
  19.     procedure FormDestroy(Sender: TObject);
  20.   private
  21.     FStudentList : TStudentList; // add the list here to make it available to all form methods
  22.   public
  23.     { Public declarations }
  24.   end;
  25.  
  26. implementation
  27.  
  28. //TStudentList
  29. procedure TStudentList.SetStudent(I: Integer; AStudent: TStudent);
  30. begin
  31.   Items[i] := AStudent;
  32. end;
  33.  
  34. function TStudentList.GetStudent(I: Integer): TStudent;
  35. begin
  36.   Result := TStudent( Items[i] );
  37. end;
  38.  
  39. //TForm1
  40. procedure TForm1.FormCreate(Sender: TObject);
  41. var
  42.   student : TStudent;
  43. begin
  44.   //Create the list when you create the main form
  45.   FStudentList := TStudentList.Create;
  46.  
  47.   //populate the list
  48.   student := TStudent.Create;
  49.   //assign values to student properties
  50.   FStudentList.Add( student );
  51.  
  52.   student := TStudent.Create; //next student
  53.   //assign values to student properties
  54.   FStudentList.Add( student ); //notice, we don't care about indexes
  55.   ...
  56. end;
  57.  
  58. procedure TForm1.FormDestroy(Sender: TObject);
  59. begin
  60.   //Destroy the list and free all student objects when the main form is being destroyed
  61.   FStudentList.Free;
  62. end;
  63.  


When you need to access particular item of the list:
FStudentList.Students[i].Name := 'Tom';
or
student := FStudentList.Students[i]

Reply With Quote
  #14  
Old May 23rd, 2008, 07:45 AM
hannesbez hannesbez is offline
Registered User
Tutorialized Newbie (0 - 499 posts)
 
Join Date: May 2008
Location: Johannesburg
Posts: 9 hannesbez User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 20 m 13 sec
Reputation Power: 0
Send a message via Skype to hannesbez
Great stuff. Thank you. Matter of interest, I sorted the List like
for i := 0 to objList.Count-1 do
for j := 0 to objList.Count-2 do
if (TStudent(objList[j]).Age) > (TStudent(objList[j+1]).Age) then
objList.Move(j, (j+1));
It works pretty well but I noticed there is a Sort method that I have not yet succeeded in finding out how it works. It may be too complex for school kids.

Reply With Quote
  #15  
Old May 23rd, 2008, 09:42 AM
UseShots UseShots is offline
Registered User
Tutorialized Newbie (0 - 499 posts)
 
Join Date: May 2008
Posts: 11 UseShots User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 h 36 m 22 sec
Reputation Power: 0
Post

Sort works like this: if you want to sort your list by Age, define a compare function

delphi Code:
Original - delphi Code
  1.  
  2. function CompareAges(Item1, Item2: Pointer): Integer;
  3. begin 
  4.   Result := TStudent(Item2).Age - TStudent(Item1).Age;
  5.   //> 0 (positive)  Item1 is less than Item2
  6.   // 0  Item1 is equal to Item2
  7.   //< 0 (negative)  Item1 is greater than Item2 
  8. end;


To sort, call
delphi Code:
Original - delphi Code
  1.  
  2.   objList.Sort(@CompareAges);

Reply With Quote
Reply

Viewing: Tutorialized ForumsDesktop ProgrammingDelphi > Dynamic Array of Objects


Developer Shed Advertisers and Affiliates


Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump


Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 

Powered by: vBulletin Version 3.0.5
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.

© 2003-2018 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap