надо ради прикола новый паскаль сделать.
1. чтоб в принципе не было ситуации в коде когда переменная имела значение nil, nil тока как тип Null, если переменная объявлена то ей задается значение до первого обращения к ней, в подавляющем большинстве случаев nil ненужен
2. никаких явных, в виде функции, с разными параметрами, конструкторов у классов, решает проблему сериализации
3. отслеживание владения, место вызова деструктора вычисляет компилятор
4. как положено if a is t then меняет тип переменной на t, не надо писать a as t
5. нет приведению типов вида TObject(a)
6. конструктор тока один TObject(), в скобках анонимный блок кода который вызывается при создании объекта и инициализирует переменные, инициализация переменных объекта значениями по умолчанию при объявлении
7. наконец то сделать нормальное определение классов, чтоб в секции interface у класса были тока protected public а то что ранее было в private в секции implementation
Код: Выделить всё
unit u1;
interface
type
TNode = class;
TNodeParent = class
protected
function GetCount: Integer;
function GetItem(Index: Integer): TNode;
public
property Count: Integer read GetCount;
property Item[Index: Integer]: TNode read GetItem;
end;
TTree = class(TNodeParent)
protected
public
end;
TNode = class(TNodeParent)
protected
FParent: TNodeParent; //так как значение по умолчанию не указано то его надо задать в конструкторе
FCaption: string; //строки по умолчанию пустые
FImageIndex: integer = -1;
procedure SetParent(Value: TNodeParent);
procedure ReleaseParent;
public
//перед вызовом write, если FParent <> nil то вызывает release
//так же из release генерируется деструктор, так как FParent пришел из вне его деструктор не вызывается
property Parent: TNodeParent read FParent write SetParent release ReleaseParent;
property Caption: string read FCaption write FCaption;
property ImageIndex: integer read FTestProp1 write FImageIndex;
end;
procedure p1(t1: TTree; n1: TNode or Null); //прям так жестко и писать через OR чтоб неповадно было
implementation
procedure p1(t1: TTree; n1: TNode or Null);
var
n2: TNode;
begin
AddLog(n1.Caption); //ошибка компиляции - так как неизвестно что там
if n1 is Null then
AddLog('Null')
else // так как на Null проверили то значит там TNode
AddLog(n1.Caption); //нормально
AddLog(n2.Caption); //ошибка компиляции - значение n2 не задано
if n1 is Null then
n2:= TNode(Parent:= t1; Caption:= 'Root1'; ImageIndex:= 1)
else
n2:= TNode(Parent:= n1; Caption:= 'Test1'; ImageIndex:= 2);
AddLog(n2.Caption); //нормально
end;
type
TNodeParent = class
//private ключевое слово ненужно
FObjectList: TObjectList = TObjectList(); //так как FObjectList создан в классе он освобождается в деструкторе класса
procedure SetParent(Node: TNode);
procedure ReleaseParent(Node: TNode);
end;
TNode = class
end;
{ TNodeParent }
function TNodeParent.GetCount: Integer;
begin
result:= FObjectList.Count;
end;
function TNodeParent.GetItem(Index: Integer): TNode;
begin
result:= FObjectList[Index] as TNode;
end;
procedure TNodeParent.SetParent(Node: TNode);
begin
FObjectList.Add(Node);
end;
procedure TNodeParent.ReleaseParent(Node: TNode);
begin
FObjectList.Remove(Node);
end;
{ TNode }
procedure TNode.SetParent(Value: TNodeParent);
begin
FParent:= Value;
FParent.SetParent(Self);
end;
procedure TNode.ReleaseParent;
begin
FParent.ReleaseParent(Self);
end;
end.