12

Delphi文档指出

永远不要直接引发EInvalidPointer异常。EInvalidPointer由内存管理器在内部引发。

我正在编写一个自定义基类作为 的替代方案TInterfacedObject,尽可能地遵循 RTL 实现,并通过示例查看TInterfacedObjectRTL 中的实现BeforeDestruction为:

procedure TInterfacedObject.BeforeDestruction;
begin
  if RefCount <> 0 then
    Error(reInvalidPtr);  
end;

Where通过 RTL 本地的各种单元范围方法提出Error(reInvalidPtr)EInvalidPointer

如果我正在编写自己的课程,我应该如何实现BeforeDestruction?为什么不这样做?:

procedure TMyInterfacedObject.BeforeDestruction;
begin
  if RefCount <> 0 then
    raise EInvalidPointer.CreateRes(@SInvalidPointer) at ReturnAddress;
end;

InvalidPointer中声明的全局异常对象有什么特别之处SysUtils吗?如果这一个坏主意,那么在这里简单地提出一个自定义异常是否明智?

4

2 回答 2

9

补充大卫的回答InvalidPointer用于提高EInvalidPointer, 以及OutOfMemory<->的特殊之处EOutOfMemory在其优势的文档主题中进行了更详细的解释EHeapException

EHeapException是与堆分配内存相关的错误的异常类。

EHeapException的后代——EOutOfMemory 和 EInvalidPointer——用于处理动态内存分配失败和无效指针操作。

注意:只要应用程序启动,这些异常的内存就会预先分配,并且只要应用程序正在运行,就会保持分配状态。永远不要直接引发EHeapException或其后代。

我猜这相当于,一旦您遇到内存问题,分配内存来创建这些错误可能是不安全的:因为缺少它或可能的损坏......

于 2016-12-20T20:19:49.647 回答
6

回避原始问题,您可以通过使用与运行时相同的代码来避免问它:

System.Error(reInvalidPtr);
于 2016-12-20T18:46:56.923 回答