Reputation: 7799
I would like to know how do I declare a record, that has some fixed values. I need to send data using this pattern: Byte($FF)-Byte(0..250)-Byte(0..250)
. I am using record
for that and I would like to have the first value of it constant, so that it can't be messed up.
Such as:
TPacket = record
InitByte: byte; // =255, constant
FirstVal,
SecondVal: byte;
end;
Upvotes: 7
Views: 6051
Reputation: 21650
You can't rely on a constructor because, contrary to Classes, Records are not required to use them, the default parameterless constructor being used implicitly.
But you can use a constant field:
type
TPacket = record
type
TBytish = 0..250;
const
InitByte : Byte = 255;
var
FirstVal,
SecondVal: TBytish;
end;
Then use this as a regular Record, except that you don't have (and you can't) change the InitByte
field.
FillChar
preserves the constant field and behaves as expected.
procedure TForm2.FormCreate(Sender: TObject);
var
r: TPacket;
begin
FillChar(r, SizeOf(r), #0);
ShowMessage(Format('InitByte = %d, FirstVal = %d, SecondVal = %d', [r.InitByte, r.FirstVal,r.SecondVal]));
// r.InitByte := 42; // not allowed by compiler
// r.FirstVal := 251; // not allowed by compiler
r.FirstVal := 1;
r.SecondVal := 2;
ShowMessage(Format('InitByte = %d, FirstVal = %d, SecondVal = %d', [r.InitByte, r.FirstVal,r.SecondVal]));
end;
Updated to include the nested type range 0..250
Upvotes: 13
Reputation: 10937
This is the most simple way:
type
TPacket = record
InitByte: byte; // =255, constant
FirstVal,
SecondVal: byte;
end;
var
Packet : TPacket = (InitByte: 255);
const
Packet1 : TPacket = (InitByte: 255);
Upvotes: 0
Reputation: 76724
Given the fact that records can now have properties, you can define a record as:
TMixedFixed = record
strict private
FFixed: byte;
FVariable1: byte;
FVariable2: byte;
public
property Fixed read FFixed;
property Variable read FVariable write FVariable;
constructor Create(Var1, Var2: byte);
end;
constructor TMixedFixed.create(Var1, Var2: byte);
begin
FFixed:= 255;
FVariable1:= Var1;
FVariable2:= Var2;
end;
Given the fact that the real variables are strict private you should not be able to touch them without special magic. You will have to use the constructor to init the 'fixed' values though.
Upvotes: 0
Reputation: 1284
Modern versions of Delphi allow record methods. While you can't prevent someone from changing the field you can at least initialize it properly:
type
TPacket = record
InitByte: byte; // =255, constant
FirstVal,
SecondVal: byte;
constructor Create(val1, val2 : byte);
end;
constructor TPacket.Create(val1, val2: byte);
begin
InitByte := 255;
FirstVal := val1;
SecondVal := val2;
end;
Upvotes: 2