Simple Class question

I want to have in a class an array like this:
type TBook = record
  name: String;
  pages: Byte;
end;

private
  A: Array of TBook;
 
let`s say I want the class to have the name TMyClass

I want to have these:
MyClass: TMyClass;

MyClass[1].BookName := 'bookname' or bookname := MyClass[1].BookName;
and I don`t want to have a maximum number of A.
Also I want MyClass.Add(book: TBook);

I want all the code pls.

Thanks.
crystyanAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

InteractiveMindCommented:
In which language?
crystyanAuthor Commented:
delphi, sorry I`ve missed that I wasn`t in the right category.

So I want it in Delphi.
kretzschmarCommented:
you can use a TList for this
Exploring ASP.NET Core: Fundamentals

Learn to build web apps and services, IoT apps, and mobile backends by covering the fundamentals of ASP.NET Core and  exploring the core foundations for app libraries.

crystyanAuthor Commented:
could u tell me how pls ?
crystyanAuthor Commented:
give me a simple example.
kretzschmarCommented:
sorry, i'm in hurry, so i have no ttime for a complete simple sample

type PBook = ^TBook; //Pointer of Record
type TBook = record
  name: String;
  pages: Byte;
end;

private
  BookList: TList;
 

create somewhere the TList
  BookList := TList.Create;

procedure TMyBookListClass.add(ABook : TBook);
var p : PBook;
begin
  new(p);
  p^.name := ABook.name;
  p^.pages := ABook.pages;
  BookList.Add(p);
end;

Procedure TMyBookListClass.Delete(AIndex : Integer);
begin
  if AIndex < BookList.Count and AIndex > -1 then
  begin
    if assigned(BookList[AIndex]) then
      Dispose(PBook(BookList[AIndex]));
    BookList.Delete(AIndex);
  end
  else Raise Exception.Create('Index out of Bounds');
end;

hope this helps a bit, just from head, typos possible

meikl ;-)




Mike LittlewoodEngineerCommented:
Something like this? (though I changed from using a record to an object to use an object list)

///////////////////////////////////////////////////////////////////////////////////////
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Contnrs, StdCtrls;

type

  TBook = class( TObject)
  public
    name: String;
    pages: Byte;
  end;

  TMyClass = class( TObjectList)
    private
      function addItem( pBook: TBook): Longint;
    public
      constructor create( pOwnsObjects: boolean = true);
    end;

    TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    private
      FMyClass: TMyClass;

      function GetMyClass: TMyClass;
    public
      procedure beforeDestruction; override;

      property MyClass: TMyClass read GetMyClass;
    end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function TMyClass.addItem( pBook: TBook): longInt;
begin
   result := add( pBook);
end;

procedure TForm1.beforeDestruction;
var
  i: Integer;
  b: TBook;
begin
   try
      for i := MyClass.Count - 1 downto 0 do
      begin
        b := TBook(MyClass.Items[i]);
        FreeAndNil(b);
      end;
   finally
      inherited;
   end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  b: TBook;
begin
  if (Trim(Edit1.Text) = '') or (Trim(Edit2.Text) = '') then Exit;

  b := TBook.Create;

  b.Name  := Trim(Edit1.Text);
  b.pages := StrToInt(Edit2.Text);

  MyClass.addItem( b);
end;

function TForm1.GetMyClass: TMyClass;
begin
  if not Assigned( FMyClass) then
    FMyClass := TMyClass.Create;

  Result := FMyClass;
end;

constructor TMyClass.create(pOwnsObjects: boolean);
begin
  inherited create( pOwnsObjects);
end;

end.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
kretzschmarCommented:
yep, a fine solution, mike
crystyanAuthor Commented:
and how could I make a property like
    property  TotalItems: Word read BookList.Count;

or how could I access TList properties ?

I want something like Book[1] := Book[2] too.

Thanks a lot !
Mike LittlewoodEngineerCommented:
type
  TMyClass .....
  private
    function GetTotalBooks: Integer;
  public
    property TotalBooks: Integer read GetTotalBooks;


function TMyClass.GetTotalBooks: Integer;
begin
  Result := FMyClass.Count
end;
Mike LittlewoodEngineerCommented:
Sorry that should be

Result := Count
crystyanAuthor Commented:
thanks, me being dumb.

but tell me about how could I do this (my last qestion):

function TWebsite.GetItem(Index: Word): TBook;
var
  p: pBook;
begin
  if (Index < Books.Count) and (Index > -1) then
  begin
    if assigned(Books[Index]) then
    begin
      new(p);
      p := Books.Items[Index];
      Result.Title := p^.Title;
      Result.Author := p^.Author;
      dispose(p);
    end;
  end;

if I put there dispose(p) I can`t access it right. If I don`t put dispose(p) I`ll alloc memory each time I read.
how could I access the content of Books[Index] without a new pointer ?

thanks in a million!
Mike LittlewoodEngineerCommented:
Not sure if you can just equate the examples like this

procedure TForm1.CopyBook(fromBook, toBook: Integer);
begin
  if (MyClass[fromBook] <> nil) and (MyClass[toBook] <> nil) then
  begin
    MyClass[toBook] := MyClass[fromBook]
  end;
end;

or if you have to change the values instead

procedure TForm1.CopyBook(fromBook, toBook: Integer);
begin
  if (MyClass[fromBook] <> nil) and (MyClass[toBook] <> nil) then
  begin
    TBook(MyClass[toBook]).name := TBook(MyClass[fromBook]).Name;
    TBook(MyClass[toBook]).pages := TBook(MyClass[fromBook]).pages;
  end;
end;
Mike LittlewoodEngineerCommented:
Shouldnt that be

function TWebsite.GetItem(Index: Word): TBook;
begin
  if (Index < Books.Count) and (Index > -1) then
  begin
    if assigned(Books[Index]) then
    begin
      Result := Books.Items[Index];
    end;
  end;
crystyanAuthor Commented:
no, cuz the result isn`t pointer ...
crystyanAuthor Commented:
I need a way to return the book. something like Books.Items[i] should return a TBook, right ?
crystyanAuthor Commented:
BookList.Items[i] I meant
Mike LittlewoodEngineerCommented:
Why do you want to return a pointer to the book when you already have the book in Books.Items[Index]

O wait, is Books your object list? You need to typcast it first in my example for the book

function TWebsite.GetItem(Index: Word): TBook;
begin
  if ( Index < Books.Count) and ( Index > -1) then
  begin
    if assigned( Books[ Index]) then
    begin
      Result := TBook( Books.Items[ Index]);
    end;
  end;
kretzschmarCommented:
seems to be a replacement, or?

<--------paste begin
function TWebsite.GetItem(Index: Word): TBook;
var
  p: pBook;
begin
  if (Index < Books.Count) and (Index > -1) then
  begin
    if assigned(Books[Index]) then
    begin
      new(p);
      p := Books.Items[Index];
      Result.Title := p^.Title;
      Result.Author := p^.Author;
      dispose(p);
    end;
  end;
>--------paste end

function TWebsite.GetItem(Index: Word): TBook;
var
  p: pBook;
begin
  if (Index < Books.Count) and (Index > -1) then
  begin
    if assigned(Books[Index]) then
    begin
      //new(p); //nothing new, just for replacement no new pointer
      p := Books.Items[Index];
      Result.Title := p^.Title;
      Result.Author := p^.Author;
      //dispose(p);  //no dispose, because you may hold the data and not free it yet
    end;
  end;
  result := p^;  //you may return the result
end;

why not use mike's sample, in this case you have no handling qith the ^-sign

meikl ;-)
kretzschmarCommented:
oops, forget the line
>  result := p^;  //you may return the result

meikl ;-)
crystyanAuthor Commented:
lol

thanks a lot! I`ve solved the prob .... it`s just my code is a mess and I`m trying to make it clean...
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.