我在运行时创建了几个TPoint
对象,但我没有销毁它们。
我查看了TPoint
中的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;
通过阅读它,我看到没有destructor
,而且它是原始记录。
我不会在某一点上掌握Delphi以确定它,但我认为不需要调用MyPoint.Free
。
有些专家可以证实吗?
答案 0 :(得分:4)
TPoint是一张唱片。
值类型
Record
和integer
等基本类型是值类型
这意味着它们是在堆栈上创建的
当函数退出时,它会清理堆栈,这样就可以回收内存空间。
参考类型
这与作为参考类型的类形成对比
在堆上创建一个类,需要显式释放。
托管类型
正好处于这两个极端之间managed types
,如string
或interface
这些是在堆上创建的,但编译器使用编译器魔术在引用计数降至零时自动销毁它们。
因为这个托管类型据说有value sementics
。
<强> ARC 强>
在ARC编译器(移动设备+ Linux)上,甚至可以使用引用计数来自动管理类。这意味着记录,类和托管类型之间的语义差异已被消除。
如果需要,您当然可以在堆上创建记录:
type
PRecord = ^TMyRecord;
var
HeapRec: PRecord;
begin
GetMem(HeapRec, SizeOf(TMyRecord));
try
do stuff with HeapRec........
finally
FreeMem(HeapRec);
请记住始终将记录作为const
参数传递(如果可能)。否则编译器将浪费时间制作记录的副本。
但....方法?
记录现在有方法。
然而,这仅仅是语法糖
您不能拥有虚拟/动态方法,也不能使用接口方法
以下两种方法完全等效:
//Pre Delphi 2006
function CloneTMyRecord(const Self: TMyRecord): TMyRecord;
//Post Delphi 2006
function TMyRecord.Clone: TMyRecord;
答案 1 :(得分:0)
我本可以删除这个问题,但由于我有疑问,所以对其他人有用。
TPoint
不是一个班级。
让我信服的是,我试图做一个像这样定义的对象列表:
uses Generics.Collections;
//
PointsList: TObjectList<TPoint>;
并且编译器告诉我
“E2511类型参数'T'必须是类类型”
所以这让我确信TPoint不是一个对象,因此不能被释放。
此外,关于将TPoint存储在List中,该线程描述了使用TList
:store array of TPoint inside TObjectList更好地使用泛型。事实上,TPoint
列表已安全地定义为TList<TPoint>
。
此外,我尝试使用Eurekalog搜索泄漏,并且未释放的TPoint
不会像未释放的TStringList
那样泄漏。
顺便说一下,在TPoint
中定义System.Types
的事实应该回复我的问题/主题标题“我在Delphi中找到一个原语吗?”