Question sur les types "record"

Signaler
Messages postés
166
Date d'inscription
mardi 11 novembre 2003
Statut
Membre
Dernière intervention
13 octobre 2008
-
Messages postés
4200
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
13 juin 2020
-
Bonjour!

Je me pose quelques questions sur les types record:

Imaginons un type:

type TMonRecord = record
  MyByte: Byte;
  MyWord: Word;
  MyString: String;
end;

var rec1,rec2 : TMonRecord;

est ce que
rec1 := rec2
est equivalent à
rec1.MyByte   := rec2.MyByte;
rec1.MyWord   := rec2.MyWord;
rec1.MyString := rec2.MyString;
?

Ensuite, je voudrais avoir une liste de TMonRecord. D'habitude pour gerer une liste d'objet j'utilise TObjectList, mais ce type de liste n'accepte pas les type record.

Avez vous une solution pour gerer une liste de TMonRecord?

Merci de votre aide!

3 réponses

Messages postés
1284
Date d'inscription
mardi 28 octobre 2003
Statut
Contributeur
Dernière intervention
3 juillet 2015
13
Salut,


Je sais pas pour la première partie de ta question, le mieux, c'est de tester ce que ça donne .

Sinon, pour faire une liste, je pense que tu peux gérer ça sans problème avec un array

Simon
Messages postés
991
Date d'inscription
samedi 25 octobre 2003
Statut
Membre
Dernière intervention
29 août 2013
5
je dirai oui pour ta premiere question, je l'ai fait avec des record contenant des extended. Par contre, si ton record contient des objets ou des pointeurs, je pense que l'affectation fera que les 2 pointeront vers le meme objet (ou variable pointée).

moi je te conseille une TList, mais ca te force a instancier toi meme des pointeurs vers ton type. un array est plus pratique et performant si le nombre d'elements reste statique. si il varie, il est preferable de faire une TList car il me semble que la modification de la taille d'un array le deplace si il n'y a pas assez de place contigue en memoire.
Messages postés
4200
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
13 juin 2020
30
en effet, deux record de même type peuvent etre utilisé de la sorte.

R1 := R2;

peu importe ce qu'il contiennent, entier, flotant, chaine, pointeur etc.

delphi copy le contenus de R2 dans R1 ...

pour ce qui est de la TList, c'est tout aussi performant qu'un Array puisque TList utilise un array (PPointerList)

faut juste deriver TList pour l'utiliser avec ton type record exemple :

type
  { TStrRecList }

  pStringRecord = ^TStringRecord;
  TStringRecord = record
    A, B : string;
  end;

  TStrRecList = class(TList)
  private
    function GetItem(index : integer) : TStringRecord;
    procedure SetItem(index : integer; val : TStringRecord);
    procedure Notify(Ptr: Pointer; Action: TListNotification); override;
  public
    property Items[Index: Integer]: TStringRecord read GetItem write SetItem; default;
    function Add(const Item: TStringRecord): Integer;
    function First: TStringRecord;
    procedure Insert(const Index: Integer; const Item: TStringRecord);
    function Last: TStringRecord;
    function IndexOf(const Item : TStringRecord) : integer;
    procedure Clear; override;
  end;

{ TStrRecList }

function TStrRecList.Add(const Item: TStringRecord): Integer;
var pR : pStringRecord;
begin
  new(pR);
  pR^ := Item;
  result := inherited Add(pR);
end;

procedure TStrRecList.Clear;
var N : integer;
begin
  for N := Count-1 downto 0 do
      Delete(N);
  inherited;
end;

function TStrRecList.First: TStringRecord;
begin
  result := pStringRecord(inherited First)^;
end;

function TStrRecList.GetItem(index: integer): TStringRecord;
begin
  result := pStringRecord(inherited Get(index))^;
end;

function TStrRecList.IndexOf(const Item: TStringRecord): integer;
var SOI : integer;
    fnditem : TStringRecord;
begin
  SOI := SizeOf(Item);

  Result := 0;
  fnditem := GetItem(result);
  while (Result < Count) and (not comparemem(@item,@fnditem,SOI)) do
  begin
    inc(Result);
    fnditem := GetItem(result);
  end;
  if Result = Count then
     Result := -1;
end;

procedure TStrRecList.Insert(const Index: Integer; const Item: TStringRecord);
var pR : pStringRecord;
begin
  New(pR);
  pR^ := Item;
  inherited Insert(index, pR);
end;

function TStrRecList.Last: TStringRecord;
begin
  result := pStringRecord(inherited Last)^;
end;

procedure TStrRecList.Notify(Ptr: Pointer; Action: TListNotification);
begin
  inherited Notify(Ptr, Action);
  if Action = lnDeleted then
     Dispose(Ptr);
end;

procedure TStrRecList.SetItem(index: integer; val: TStringRecord);
var pR : pStringRecord;
begin
  pR := pStringRecord(inherited Get(index));
  pR^:= val;
end;

exemple d'utilisation :

procedure TForm1.FormCreate(Sender: TObject);
var R  : TStringRecord;
    RL : TStrRecList;
    I  : integer;
begin
  RL  := TStrRecList.Create;
  try
    R.A := 'hello';
    R.B := 'world';
    I   := RL.Add(R);
    R   := RL.Last; // ou RL.Items[I]

    ListBox1.Items.Add(IntToStr(RL.IndexOf(R))+'/'+R.A+'/'+R.B);

    R.A := 'hEllO';
    R.B := 'wOrld';
    I   := RL.Add(R);
    R   := RL.Last; // ou RL.Items[I]

    ListBox1.Items.Add(IntToStr(RL.IndexOf(R))+'/'+R.A+'/'+R.B);

    R.A := '';
    R.B := '';

  finally
    RL.Clear;
    RL.Free;
  end;
end;

<hr size="2" width="100%" />Croc (click me)