TPoint 是 Delphi 中的原语吗?

LaB*_*cca 0 memory delphi primitive destructor delphi-10-seattle

TPoint在运行时创建了几个对象,但我没有销毁它们。

我检查了TPointin的代码System.Types

PPoint = ^TPoint;
  TPoint = record
    X: FixedInt;
    Y: FixedInt;
  public
    constructor Create(P : TPoint); overload;
    constructor Create(const X, Y : Integer); overload;

    //operator overloads
    class operator Equal(const Lhs, Rhs : TPoint) : Boolean;
    class operator NotEqual(const Lhs, Rhs : TPoint): Boolean;
    class operator Add(const Lhs, Rhs : TPoint): TPoint;
    class operator Subtract(const Lhs, Rhs : TPoint): TPoint;

    class operator Implicit(Value: TSmallPoint): TPoint;
    class operator Explicit(Value: TPoint): TSmallPoint;

    class function PointInCircle(const Point, Center: TPoint; const Radius: Integer): Boolean; static; inline;
    /// <summary> Zero point having values of (0, 0). </summary>
    class function Zero: TPoint; inline; static;

    function Distance(const P2 : TPoint) : Double;

    procedure SetLocation(const X, Y : Integer); overload;
    procedure SetLocation(const P : TPoint); overload;
    procedure Offset(const DX, DY : Integer); overload;
    procedure Offset(const Point: TPoint); overload;
    function Add(const Point: TPoint): TPoint;
    function Subtract(const Point: TPoint): TPoint;
    function IsZero : Boolean;

    function Angle(const APoint: TPoint): Single;
  end;
Run Code Online (Sandbox Code Playgroud)

通过阅读它,我看到没有destructor,而且它是原语的记录。我没有掌握 Delphi 来确定它,但我认为不需要调用MyPoint.Free. 有专家可以确认一下吗?

Joh*_*ica 6

TPoint 是一个记录。

值类型
Record和基本类型integer都是值类型。
这意味着它们是在堆栈上创建的。
当函数退出时,它会清理堆栈并回收内存空间。

引用类型
这与作为引用类型的类形成对比。
一个类是在堆上创建的,需要显式释放。

托管类型
就在这两个极端之间,managed types例如stringinterface
它们是在堆上创建的,但是当它们的引用计数下降到零时,编译器使用编译器魔术来自动销毁它们。因为这个托管类型据说有value sementics.

ARC
在 ARC 编译器(移动 + Linux)上,甚至使用引用计数自动管理类。这意味着记录、类和托管类型之间的语义差异已被消除。

如果需要,您当然可以在堆上创建记录:

type
  PRecord = ^TMyRecord;
var
  HeapRec: PRecord;
begin
  GetMem(HeapRec, SizeOf(TMyRecord));
  try
    do stuff with HeapRec........
  finally
   FreeMem(HeapRec);
Run Code Online (Sandbox Code Playgroud)

请记住始终将记录作为const参数传递(如果可能)。否则编译器将浪费时间制作记录的副本。

但是……方法?
这些天记录有方法。
然而,这只是语法糖。
你不能有虚拟/动态方法,也不能有接口方法

以下两种方法完全等效:

//Pre Delphi 2006
function CloneTMyRecord(const Self: TMyRecord): TMyRecord;

//Post Delphi 2006
function TMyRecord.Clone: TMyRecord;
Run Code Online (Sandbox Code Playgroud)