对象和引用有什么区别?

Rav*_*123 33 delphi

有什么区别

TFuncOfIntToString = reference to function(x: Integer): string; 
Run Code Online (Sandbox Code Playgroud)

TFuncOfIntToString = function(x: Integer): string of object; 
Run Code Online (Sandbox Code Playgroud)

我使用的是对象

Dav*_*nan 82

让我们考虑以下三种类型声明:

TProcedure = procedure;
TMethod = procedure of object;
TAnonMethod = reference to procedure;
Run Code Online (Sandbox Code Playgroud)

这些都非常相似.在调用这三种类型中的每一种的实例方面,调用代码是相同的.差异出现在可以分配给这些类型的变量的内容中.

程序类型

TProcedure是一种程序类型.您可以TProcedure为此形式的某些类型的变量分配:

procedure MyProcedure;
begin
end;
Run Code Online (Sandbox Code Playgroud)

这是一个非面向对象的过程.您不能将实例或类方法分配给TProcedure变量.但是,您可以为变量分配静态类方法TProcedure.

方法指针

TMethod是一个方法指针.这通过存在来表示of object.当你有一个类型的变量时,TMethod你必须分配:

  1. 实例化对象的实例方法,或
  2. 一种类方法.

所以你可以指定其中任何一个:

procedure TMyClass.MyMethod;
begin
end;

class procedure TMyClass.MyClassMethod;
begin
end;
Run Code Online (Sandbox Code Playgroud)

过程类型和方法指针之间的最大区别在于后者包含对代码和数据的引用.方法指针通常称为双指针过程类型.包含方法指针的变量包含对代码的引用以及要调用它的实例/类.

请考虑以下代码:

var
  instance1, instance2: TMyClass;
  method1, method2: TMethod;
....
method1 := instance1.MyMethod;
method2 := instance2.MyMethod;
Run Code Online (Sandbox Code Playgroud)

现在,尽管method1并且method2引用了同一段代码,但它们与不同的对象实例相关联.所以,如果我们打电话

method1();
method2();
Run Code Online (Sandbox Code Playgroud)

我们正在调用MyMethod两个不同的实例.该代码相当于:

instance1.MyMethod();
instance2.MyMethod();
Run Code Online (Sandbox Code Playgroud)

匿名方法

最后我们来匿名方法.这些甚至比过程类型和方法指针更通用.您可以将以下任何内容分配给使用reference to语法定义的变量:

  1. 一个简单的非面向对象的过程.
  2. 实例化类的实例方法.
  3. 一种类方法.
  4. 匿名方法.

例如:

var
  AnonMethod: TAnonMethod;
....
AnonMethod := MyProcedure;            // item 1 above
AnonMethod := instance1.MyMethod;     // item 2
AnonMethod := TMyClass.MyClassMethod; // item 3
Run Code Online (Sandbox Code Playgroud)

匿名方法,上面的第4项,是在代码中内联声明的方法.例如:

var
  AnonMethod: TAnonMethod;
....
AnonMethod := procedure
  begin
    DoSomething;
  end;
Run Code Online (Sandbox Code Playgroud)

与过程类型和方法指针相比,匿名方法的最大好处是它们允许变量捕获.例如,考虑以下简短程序来说明:

{$APPTYPE CONSOLE}
program VariableCapture;

type
  TMyFunc = reference to function(X: Integer): Integer;

function MakeFunc(Y: Integer): TMyFunc;
begin
  Result := function(X: Integer): Integer
    begin
      Result := X*Y;
    end;
end;

var
  func1, func2: TMyFunc;

begin
  func1 := MakeFunc(3);
  func2 := MakeFunc(-42);
  Writeln(func1(4));
  Writeln(func2(2));
  Readln;
end.
Run Code Online (Sandbox Code Playgroud)

这有以下输出:

12
-84

  • 在我到达谷底之前,为什么我知道这是你? (12认同)
  • @ComputerSaysNo非常感谢你,但是当你说"很少"时,我并不完全赞同你.我认为在这里有很多活跃的德尔福应答者回答了很好的解释.我不会说出名字,但我们这些活跃在这里的人知道他们是谁.我们都应该通过我们的投票来寻求通过解释来回答. (6认同)
  • 这是一个伟大而伟大的答案. (4认同)
  • 谢谢@Nick,虽然我不确定伟大.就个人而言,我有点难过没人找到我的复活节彩蛋了:http://stackoverflow.com/questions/14932549/chr-equivalent-for-unicode-in-delphi-7/14932710#14932710 (2认同)

klu*_*udg 7

第一种是匿名方法,第二种是普通方法.