Delphi - 如果没有创建类,为什么这个函数有效?

Hen*_*ria 5 delphi class function

考虑这个课程:

unit Unit2;

interface

type

  TTeste = class
  private
    texto: string;
  public
    function soma(a, b: integer): string;
  end;

implementation

procedure TForm2.Button1Click(Sender: TObject);
var
  teste: TTeste;
begin
  teste:= nil;
  teste.texto:= '';//access violation
  showmessage(teste.soma(5, 3));//no access violation
end;

{ TTeste }

function TTeste.soma(a, b: integer): string;
begin
  result:= (a+b).ToString;
end;

end.
Run Code Online (Sandbox Code Playgroud)

它真的有效吗?为什么?var崩溃了但功能没有,它是否像类功能一样工作?

Jer*_*dge 13

这是有效的,因为您没有尝试访问该类的任何字段.该功能不需要任何内存分配.如果texto在该函数中使用该字段,那么它将崩溃(正如您在其他测试中看到的那样),因为该内存未被解决.但在这里,没有涉及的记忆.两者ab(以及该问题的函数结果)都分配在类之外的其他地方.实例化过程的一部分是为对象中的每个字段分配内存.

这只是巧合.实际上使用这样的东西仍然非常气馁.如果您觉得需要在没有实例化的情况下访问该函数,那么您应该将其设置为类函数.

  • 您仍然可以在不访问标记方法虚拟的任何字段的情况下使其崩溃.然后,编译器必须确定实例(没有)类型. (7认同)
  • 如果方法不使用实例的任何字段,我倾向于使它成为静态类函数.这样,任何访问实例字段的尝试(例如在修改之后)都不会编译. (7认同)
  • @Silver:检查Self为**`nil`**与访问不存在的对象的字段不同.但这里的巧合是该方法(现在)不访问任何实例字段.所以是的,巧合的是它不会崩溃.无论如何,不​​接触实例字段的方法应该是类方法,最好是静态的. (3认同)
  • 我不同意这是巧合.此功能在TObject.Free中使用,如果对象为零,则不会引发AV.实际上,它会检查Self <>是否为零.任何非虚拟和非动态方法都可以访问,只要它不接触任何字段即可. (2认同)
  • @Rudy是绝对正确的.如果方法不(逻辑上)依赖于特定实例,请使用类方法. (2认同)