gpt4 book ai didi

delphi - Delphi 真的比处理静态类更好地处理动态类吗?

转载 作者:行者123 更新时间:2023-12-03 17:04:04 24 4
gpt4 key购买 nike

我不止一次被告知 Delphi 处理动态类比静态类更好。因此使用以下内容:

type Tsomeclass=class(TObject)
private procedure proc1;
public
someint:integer;
procedure proc2;
end;

var someclass:TSomeclass;

implementation

...

initialization
someclass:=TSomeclass.Create;
finalization
someclass.Free;

而不是

type Tsomeclass=class
private class procedure proc1;
public
class var someint:integer;
class procedure proc2;
end;

我正在处理的项目中 90% 的类只有一个实例并且只需要一个实例。我真的必须使用第一种方法来使用这些类吗?它是否经过更好的优化,由 Delphi 处理?

对不起,我没有论据支持这个假设,但我需要专家的意见。

提前致谢!

最佳答案

如果你创建一个只包含类变量和类方法的类,那么你可以在没有实例化的情况下使用它。 IE。在您的第二个示例中,您可以使用 Tsomeclass.proc2(但不能使用 Tsomeclass.someint,因为这个变量没有像 Uwe 指出的那样标有“class”前缀)。

对于(无法测量的小)速度差异,您还可以将类方法标记为“静态”。

type
TSomeclass = class
class procedure proc2; static;
end;

在我看来,这里没有“处理得更好”的比较。 Delphi 允许您在类中放置“普通”和“类”成员。前者你只能在实例化对象上使用,后者你可以在任何地方使用。但这只是 Delphi 中 OO 支持的两个部分。

编辑:回答关于速度的问题......

让我们编写一个小测试程序:

program Project61;

{$APPTYPE CONSOLE}

type
TTestClass = class
procedure A(a: integer);
class procedure B(b: integer);
class procedure C(c: integer); static;
end;

procedure TTestClass.A(a: integer); begin end;
class procedure TTestClass.B(b: integer); begin end;
class procedure TTestClass.C(c: integer); begin end;

var
tc: TTestClass;

begin
tc := TTestClass.Create;
tc.A(42);
tc.B(42);
tc.C(42);
tc.Free;
//TTestClass.A(42); // not possible
TTestClass.B(42);
TTestClass.C(42);
end.

启用优化的 Delphi 2010 将 .A/.B/.C 调用编译成

Project61.dpr.30: tc := TTestClass.Create;
004060C5 B201 mov dl,$01
004060C7 A154594000 mov eax,[$00405954]
004060CC E847DAFFFF call TObject.Create
004060D1 8BD8 mov ebx,eax
Project61.dpr.31: tc.A(42);
004060D3 BA2A000000 mov edx,$0000002a
004060D8 8BC3 mov eax,ebx
004060DA E899F9FFFF call TTestClass.A
Project61.dpr.32: tc.B(42);
004060DF BA2A000000 mov edx,$0000002a
004060E4 8B03 mov eax,[ebx]
004060E6 E891F9FFFF call TTestClass.B
Project61.dpr.33: tc.C(42);
004060EB B82A000000 mov eax,$0000002a
004060F0 E88BF9FFFF call TTestClass.C
Project61.dpr.34: tc.Free;
004060F5 8BC3 mov eax,ebx
004060F7 E84CDAFFFF call TObject.Free
Project61.dpr.36: TTestClass.B(42);
004060FC BA2A000000 mov edx,$0000002a
00406101 A154594000 mov eax,[$00405954]
00406106 E871F9FFFF call TTestClass.B
Project61.dpr.37: TTestClass.C(42);
0040610B B82A000000 mov eax,$0000002a
00406110 E86BF9FFFF call TTestClass.C

首先创建对象并将其地址存储到 ebx 寄存器中。

为了调用 tc.A,编译器在 edx 中准备参数(42 或 $2A),在 eax 中准备“tc”实例的地址并调用 TTestClass.A。

几乎相同的情况发生在 tc.B 的情况下,除了 ebx 被取消引用。

在 .A 和 .B 的情况下,eax 包含“Self”的值(相当于 C++ 的“this”)。调用 tc.A 时,eax 包含“tc”实例的地址。调用 tc.B 时,eax 包含其他内容(我猜它指向 TTestClass 的类型信息,但我不太确定)。

当代码调用 tc.C 时,只准备 eax,因为“静态”方法不能引用“Self”。

类似的情况发生在 TTestClass.B/.C 的情况下,除了当 ??TTestClass 类型信息的地址?被储存了。无论如何,当 B 通过实例 (tc.B) 或通过类 (TTestClass.B) 调用时,eax 包含相同的值。

所以你可以看到静态调用需要少一个'mov'。这就是我所指的不可估量的加速。

关于delphi - Delphi 真的比处理静态类更好地处理动态类吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2612901/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com