Статические классы и дженерики (Delphi)
От: Khimik  
Дата: 07.12.18 07:40
Оценка:
Я оптимизировал один алгоритм в своей программе, и всё время возникали баги-проблемы (больше всего от неудаления динамических массивов и неосторожной передачей этих массивов как параметры функций). В итоге я решил основательно всё переписать, в частности заменил большинство своих динамических массивов на вот такие классы:

TIntArray=class(TSafeObject)
private
fitems:pintarr;
fcount,fcapacity:integer;
procedure SetCapacity(newcapacity:integer);
procedure SetCount(newcount: integer);
function GetItem(index: integer): integer;
procedure SetItem(index: integer; Value: integer);

public
property Capacity:integer read fcapacity write SetCapacity;
property Count:integer read fcount write SetCount;
property Items[index:integer]:integer read GetItem write SetItem; default;
procedure Assign(otherarray:tintarray);
procedure RoundAssign(othervalarray:tdoublearray);
function Find(value:integer):integer;
procedure Clear;
procedure Grow;
procedure Add(value:integer);
procedure AddNew(value:integer);//Добавляет элемент, если его еще нет в массиве
procedure AddArray(otherarray:tintarray);
procedure AddNewValuesFromArray(otherarray:tintarray);
procedure Delete(index:integer);
procedure SwapPoints(pointnum1,pointnum2:integer);//меняет местами два элемента
procedure MoveItemToTheFirst(itemnum:integer);//переводит указанный элемент в начало массива
//(остальные элементы сдвигаются на единицу вверх)
procedure ExcludeOtherArray(otherarray:tintarray);//Удаляет все элементы, входящие во второй массив.
procedure KeepOtherArray(otherarray:tintarray);//Оставляет только элементы, входящие во второй массив.
procedure SetBackPointers(otherarray:tintarray);//Во втором массиве должны находиться указатели
//на текущий (не повторяющиеся); в items расставляются номера этих указателей или -1, где их нет.
//Перед вызовом должен быть установлен count
function GetUniqueValsNumbers:tintarray;//Возвращает массив, состоящий из 0, 1, 2..., соответствующим
//уникальным числам в исходном массиве
procedure Sort(ascending:boolean);
procedure FillWithValues(valuesbeg,valueslast:integer);
procedure IncValues(add:integer);
procedure AddToStream(stream:tstream);
procedure ReadFromStream(stream:tstream);
procedure WriteToStream(stream:tstream);
destructor Destroy; override;
end;


Эти классы всем хороши (особенно после того как я подключил к программе свой сборщик мусора
Автор: Khimik
Дата: 30.11 14:20
), за исключением скорости: они представляют собой указатель на указатель и ещё на индекс, т.е. три указателя.
Поэтому я думаю заменить часть этих классов на такие record-ы:

TRiIntArray=record
FItems:pintarr;
FCount,FCapacity:integer;
FTag:integer;
procedure SetCapacity(newcapacity:integer);
procedure SetCount(newcount: integer);
function GetItem(index: integer): integer;
procedure SetItem(index: integer; Value: integer);
property Capacity:integer read fcapacity write SetCapacity;
property Count:integer read fcount write SetCount;
property Items[index:integer]:integer read GetItem write SetItem; default;
procedure Assign(otherarray:triintarray);
function Find(value:integer):integer;
procedure Clear;
procedure Grow;
procedure Add(value:integer);
procedure Delete(index:integer);
procedure Sort(ascending:boolean);
procedure AddToStream(stream:tstream);
procedure ReadFromStream(stream:tstream);
procedure WriteToStream(stream:tstream);
procedure Initialize;
procedure Finalize;
end;


Можно ли назвать такие record-ы статическими классами? У них есть инкапсуляция, но нет наследования и полиморфизма (наследование кстати авторам ЯП было бы нетрудно добавить).
Проблема для меня в том, что нельзя писать такой record для каждого нового типа данных, а ещё по этой причине не получится так сделать двумерные динамические массивы. Но может быть эту проблему можно решить с помощью дженериков? Я пока не освоился с дженериками в Delphi, примеры на сайте связаны с классами, а с рекордами их не применишь?

Ещё мне интересно, как выглядят статические классы в C++, насколько похожие там были бы проблемы.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.