Вопрос по указателям для типа record (Delphi)
первоначальная задача, насколько я понимаю - очистить все поля записи одним махом. Можно это сделать через вариантные массивы
поле RecArr хранится по тому же адресу, что и a1, a2,a3 - можно обнулить массив и обнулятся a1,a2,a3
TMyRec = record
case Integer of
1: (a1: Integer;
a2: Integer;
a3: Integer);
2: (RecArr: array [0..3*SizeOf(Integer) - 1] of byte);
end;
поле RecArr хранится по тому же адресу, что и a1, a2,a3 - можно обнулить массив и обнулятся a1,a2,a3
Если тебе их нужно инициализировать нулем, то используй
Если тебе их нужно инициализировать не нулем, то нужно переходить на object (пока виртуальные методы не используются, он ведет себя как record):
fillchar(prec^,sizeof(prec^0);
Если тебе их нужно инициализировать не нулем, то нужно переходить на object (пока виртуальные методы не используются, он ведет себя как record):
type
TMyRec=object
a:integer;
b:integer;
c:integer;
d:array of integer;
constructor init;
destructor done;
end;
constructor TMyRec.init;
begin
a:=2;
b:=1;
c:=0;
d:=nil;
end;
destructor TMyRec.done;
begin
setlength(d,0);
end;
var
rec:^TMyRec;
begin
new(rec,init);
writeln(rec^.a,',',rec^.b,',',rec^.c);
dispose(rec,done);
end.
Хорошо, а если в записи присутствуют разнородные данные, в том числе строки, массивы строк и др.?
Попробую, спасибо.
Да, ещё: если методом fillchar заполнить выделенную память нулями, то как поведут себя поля с типом, отличным от integer? Как проще всего проинициализировать строковые переменные в записи, чтобы там не оказался "мусор"?
если использовать строки с фиксированной длиной, то в записи выделяется память для них, ссылки не используются
если используются разнородные данные, содержащие ссылки, то наверно, вместо записей надо использовать классы с published-секцией и получить информацию о количестве и типах полей в runtime
если используются разнородные данные, содержащие ссылки, то наверно, вместо записей надо использовать классы с published-секцией и получить информацию о количестве и типах полей в runtime
На сколько я знаю, типы вещественных данных при этом инициализируются нулем. Строки переменной длины инициализируются nil, что для паскаля равносильно пустой строке. Вот только с variant будут проблемы и, возможно, с множествами.
Попробовал через fillchar на разных типах полей (целое, строка, массив строк, булев тип). Всё ok.
С конструктором-деструктором инициализация тоже хороший вариант. В общем, спасибо други!
С конструктором-деструктором инициализация тоже хороший вариант. В общем, спасибо други!
Оставить комментарий
dimon72
Ковыряюсь тут с одной прогой. Работаю с записями. Понадобилось очищать все поля записи одним махом. Задумался как реализовать. Напрямую, видимо, не получается. Начал делать через указатели. Получилось. Выяснилась одна неприятная особенность: когда работаешь с фактическими записями, то они всегда нормально инициализируются Delphi, наподобие глобальных переменных. Если работаешь с указателем на запись, то получается, что до присвоения какому-либо полю значения оно не определено. Всё вроде понятно, так и должно быть, очевидно. Только вот незадача: прога была ориентирована на негласную инициализацию, а тут заглючила, поскольку поля записей стали вести себя наподобие локальных переменных.--------------------------------------------------------------------------------------------------------
Type
TMyRec = Record
a: integer;
b: integer;
c: integer;
d: array of integer;
end;
var
PRec: ^TMyRec;
new(PRec);
//пока полям не присвоены числа, их значения не определены!
With PRec^ do
begin
a:=100; b:=200; c:=300;
SetLength(d,5);
d[0]:=1; d[1]:=2; d[2]:=3; d[3]:=4; d[4]:=5;
end;
dispose(PRec);
-------------------------------------------------------------------------------------------------------
Вопрос: как мне инициализировать поля записей, когда они используются через указатель, не обращаясь отдельно к каждому полю?