This question has come up in the newsgroups reasonably frequently eventhough there is a help topic all about it filed in the index under theentry “record constants,” so besure to consult the help as well.
Let us begin with an example from the Delphi source code. Consider theUtilWindowClass
variable from theClasses
unit. Delphi uses the variable in implementing theAllocateHWnd
function. Since most of the fields are staticand known in advance, the variable is initialized where it is declared,as shown in Listing 1. Only the hInstance
fieldgets set at run time.
Listing 1
A record variable with initialization from Classes.pas
var
UtilWindowClass: TWndClass = (
style: 0;
lpfnWndProc: @DefWindowProc;
cbClsExtra: 0;
cbWndExtra: 0;
hInstance: 0;
hIcon: 0;
hCursor: 0;
hbrBackground: 0;
lpszMenuName: nil;
lpszClassName: 'TPUtilWindow');
Note that the entire value is wrapped in parentheses, and each fieldname precedes a constant expression. Semicolons separate the pairs ofnames and values.
The fields must occur in the same order in which they appear in therecord type’s declaration. Any field may be omitted, but allsubsequent fields must also be omitted. Any omitted field is initializedwith the default value for itstype.
Arrays of records
To initialize an array constant, the elements’ values need toappear in a comma-separated list within a set of parentheses. Combinethis with the syntax above for record constants to reveal that arrays ofrecords should be initialized with comma-separated lists of parenthesizedsemicolon-separated lists of field: value pairs.
For example, suppose a simple command interpreter has a handfulbuilt-in commands, each implemented with a different function. Theprogram could use a record type to associate a command name with ahandler function and a short description of the command, and shownbelow.
Listing 2
Type declarations for a simple command interpreter
type
TArgArray = array of WideString;
TCommandProcessor = procedure(const Arguments: TArgArray);
TCommand = record
Command: WideString;
Processor: TCommandProcessor;
Description: PResStringRec;
end;
The program could then use an array to keep a list of all the built-infunctions the program recognizes. As with all array constants, the arraymust have constant dimensions; Delphi does not allow dynamic-arrayconstants other than nil
.
Listing 3
An array of built-in commands for a simple command interpreter
// Declarations of command handlers
procedure DoHelp(const Args: TArgArray); forward;
procedure DoExit(const Args: TArgArray); forward;
procedure DoChdir(const Args: TArgArray); forward;
procedure DoHistory(const Args: TArgArray); forward;
resourcestring
// Help messages
RsHelp = 'Print this help message';
RsExit = 'Quit the command interpreter';
RsChdir = 'Change the working directory';
RsHistory = 'Display the command history';
const
{$TYPEDADDRESS OFF}
Builtins: array[0.4] of TCommand = (
(Command: 'help'; Processor: DoHelp; Description: @RsHelp),
(Command: 'exit'; Processor: DoExit; Description: @RsExit),
(Command: 'cd'; Processor: DoChdir; Description: @RsChdir),
(Command: 'chdir'; Processor: DoChdir; Description: @RsChdir),
(Command: 'history'; Processor: DoHistory; Description: @RsHistory)
);
{$TYPEDADDRESS ON}
Initializing a record constantHi, I have a simple problem, which solution I was unable to find in the Delphi's help. I've tried const because that's the way it is done in C++ and Java. |
Re:Initializing a record constantQuoteProbe wrote: TMyRecord = record a, b, c : Integer end; TMyRecordType = array[0.2] of TMyrecord; then this should do (untested): const Regards, |
Re:Initializing a record constantQuote'Probe' <[email protected]> wrote in message news:3c7116b7$1_2@dnews.. Object Pascal Reference | Data Types, Variables, and Constants | Declared |
Re:Initializing a record constantIn article <3c7116b7$1_2@dnews>, Probe says.. Quote> const type const -- |
1. Initializing Record constants
2. Using constant record to populate another constant record
3. Initializing an array constant ?
Delphi Initialise Record
4. How to use initialized constant variable..
5. SQL - problems with inserting record, giving constants and a SELECT statement
6. Constant array of records containing a pointer problem
7. syntax for constant array of records of strings
8. DRC Delete Record constant
9. Record constants
10. constants in record types
Initializing arrays of record.Hello everybody. How can I initialize an array of records, like # type Can I initialize the array in the 'var' section? ExampleArray : array[1.N] of Example = ( (1, 'example 1'), (2, 'example Can it be done? Probably my syntax interpretation is wrong, but I have no ExampleArray[1].id := 1; Any help would appreciated ---------------------- [email protected] |
Re:Initializing arrays of record.QuotePierre Leon wrote: Quote> # type to declare a initialised record constant, you have to precede each field value by the field identifier, in your case: ExampleArray : ARRAY[1.N] OF Example = ( (id: 1; content : 'example 1'),..); Also, note the semi-colons separating the fields (instead of commas). Good luck, Remco -- |
Re:Initializing arrays of record.On 25 Aug 97 15:55:19 GMT, 'Pierre Leon' <[email protected]> wrote: Quote>Hello everybody. you can initialize only CONST array and not that ones in the VAR section. the way you initialize the array above can be done only with CONST arrays. Bye |
1. Initializing an array of records
2. Re-initialize and array?
3. Initialize an array of structs?
4. How to declare and initialize dynamic array ?
5. Tips on dynamic arrays, and help with dynamic arrays of records
6. initializing arrays: General Protection Exception
7. adding/deleting records from array of records in .dat file
8. TDBNavigator / change record position / initialize
9. Need help in initializing records
10. initializing record variables
Finalize should be used only in Delphi code where a dynamically allocated variable is deallocated by other means than the Dispose procedure. Dynamic arrays can never be deallocated using the Dispose procedure, but can be freed by passing them to Finalize.
For global variables, local variables, objects, and dynamic variables deallocated using Dispose, the compiler generates code that finalizes all long strings, variants, and interfaces contained by the variable when the instance is destroyed.
If a dynamic variable meets the following two conditions, a call to Finalize is required to finalize the variable before it can be deallocated.
The variable is deallocated by other means than the Dispose standard procedure (for example using FreeMem).
The variable contains long strings, variants, or interfaces, not all of which are empty or Unassigned.
Finalize simply sets all long strings to empty and all variants and interfaces to Unassigned, thus properly releasing any memory that was referenced by the long strings and variants.
In cases where several variables are deallocated in a contiguous memory block such as a dynamically allocated array of strings, the additional Count parameter can be specified to finalize all variables in one operation.
If the variable specified in a call to Finalize contains no long strings, variants, or interfaces, the compiler eliminates the call and generates no code for it.
Delphi Examples:
To initialize Delphi records I've always added a method (class or object) that would initialize to known good defaults. Delphi also allows for defining record 'constructors' with parameters, but you cannot define your own parameter-less 'constructor'.
Given the record above there is no warning that a record has not been initialized. Developers may neglect to call Init
on the record. Is there a way to automatically initialize records to my default, potentially more than just a simple FillChar
;
For instance
How can a record be initialized to my defaults automatically?
[Note]I don't want to modify the problem after it has been answered. Any readers are directed to read the comments on best practices on using class methods for initialization instead of a mutating object method.
2 Answers
You can use a hidden string field (which is automatically initialized to an empty string) to implement 'on time' initialization and implicit operators to hide implementation details. The code below shows how to implement a 'double' field which is automatically initialized to Pi.
There's, however, no nice way to make this solution more generic regarding the default value -- if you need a different default value you have to clone TAutoDouble definition/implementation and change the default value.
AFAIK you can't without resorting to tricks that aren't worth it (maybe using interface fields which are guaranteed to be initialized).