Delphi 类析构函数

发布于 2025-01-16 16:04:27 字数 741 浏览 0 评论 0原文

我不明白类析构函数是如何工作的!我阅读了类析构函数的语法语义和语法,但我还没有找到很多完整的代码示例。

我尝试创建一个简单的代码(见下文),该代码最终显示开始,但不显示完成

您能帮我找到一种方法,通过更改 Project1.dprUnit1.pas 中的以下代码来显示 Finish 吗?

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  Unit1 in 'Unit1.pas';

begin
  Race:= TRace.Create;
  Race.Destroy;
  Readln
end.
unit Unit1;

interface

type
  TRace= class
    class constructor Start;
    class destructor Finish;
  end;

var
  Race: TRace;

implementation

class constructor TRace.Start;
begin
  Writeln('Start')
end;

class destructor TRace.Finish;
begin
 Writeln('Finish')
end;

end.

我使用 Delphi Sydney 10.4 社区版。 谢谢

I don't understand how a class destructor works! I read grammar semantics and syntax for a class destructor, but I haven't found many complete code examples.

I tried to create a simple code (see below), and that code eventually displays Start, but it does not display Finish.

Can you help me find a way how to display Finish by changing the code below within Project1.dpr and Unit1.pas?

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  Unit1 in 'Unit1.pas';

begin
  Race:= TRace.Create;
  Race.Destroy;
  Readln
end.
unit Unit1;

interface

type
  TRace= class
    class constructor Start;
    class destructor Finish;
  end;

var
  Race: TRace;

implementation

class constructor TRace.Start;
begin
  Writeln('Start')
end;

class destructor TRace.Finish;
begin
 Writeln('Finish')
end;

end.

I use Delphi Sydney 10.4 Community Edition.
Thx

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你好,陌生人 2025-01-23 16:04:27

类析构函数将在类本身(而不是类的实例)被释放时运行,而不是针对任何单独的对象。类构造函数将在类本身创建时运行。

这意味着,当加载类时(在初始化类代码所在的可执行文件或包期间),将运行类构造函数,而当卸载(或处置)类时(在终结期间),将运行类析构函数正在运行。

该类是一个 TClass,而该类的实例是 TObject 的后代(在您的示例中为 TRace)。因此,如果您创建一个 TRace,它不会调用 TRace 的类构造函数,同样,如果您处置一个 TRace,它也不会调用调用TRace的类析构函数。

@RemyLebeau 在他的评论中链接到的文档清楚地表明这些方法“开发人员不可用” - 您永远不会调用它们,系统会调用它们。

要获得您想要的东西,您只需要一个普通的实例析构函数,如下所示:

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}
type
  TRace= class(TObject)
  public
    constructor Create;    // by convention we use Create
    destructor Destroy; override;
  end;

constructor TRace.Create;
begin
  Writeln('Start');
  inherited Create();
end;

destructor TRace.Destroy;
begin
  Writeln('Finish');
  inherited;
end;

var
  Race: TRace;

begin
  Race:= TRace.Create;
  Race.Free;
  Readln;
end.

使用类构造函数和/或类析构函数是一个不寻常的要求。它可用于初始化类运行所需的静态资源,但从我看到的代码来看,更常见的是在初始化和终结中完成此操作代码>部分。

在 Delphi 中,class 方法是通过 Self 引用类(TClass)而不是类的实例来调用的,因此它们无法访问任何实例数据,但仍然可以访问任何静态数据。

The class destructor will run when the class itself (not an instance of the class) is disposed of, not for any individual object. The class constructor will run when the class itself is created.

What that means is that when the class is loaded (during the initialization of the executable or package that the class code is in) the class constructor is run, and when the class is unloaded (or disposed of) (during finalization) the class destructor is run.

The class is a TClass, whereas instances of that class are descendants of TObject (TRace in your example). So if you create a TRace it does not call the class constructor for TRace, similarly if you dispose of a TRace it does not call the class destructor for TRace.

The documentation which @RemyLebeau linked to in his comments makes it clear that these methods are 'not available to developers' - you don't ever call them, the system does.

To get what you want you just need an ordinary instance destructor as shown:

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}
type
  TRace= class(TObject)
  public
    constructor Create;    // by convention we use Create
    destructor Destroy; override;
  end;

constructor TRace.Create;
begin
  Writeln('Start');
  inherited Create();
end;

destructor TRace.Destroy;
begin
  Writeln('Finish');
  inherited;
end;

var
  Race: TRace;

begin
  Race:= TRace.Create;
  Race.Free;
  Readln;
end.

Using a class constructor and / or a class destructor is an unusual requirement. It could be used to initialise static resources that are needed for the class to operate, but from code that I have seen it is more usual for this to be done in the initialization and finalization sections.

In Delphi class methods are called with Self referring to the class (a TClass) and not to an instance of the class and so they cannot access any instance data, but can still access any static data.

若无相欠,怎会相见 2025-01-23 16:04:27

大卫的评论是正确的。我在 Writeln('Finish') 下面添加了 Readln 并且它起作用了。

这是因为终结是类析构函数放置其命令的地方,而终结是最后出现的。

David's comment is correct. I have added Readln below Writeln('Finish') and it worked.

It's because finalization is the place where class destructor places its commands in, and finalization comes very last.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文