对象和引用有什么区别? [英] What is the difference between of object and reference to?

查看:118
本文介绍了对象和引用有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  TFuncOfIntToString =引用函数(x:Integer):string; 

  TFuncOfIntToString = function(x:Integer):对象的字符串; 

我使用对象

解决方案

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

  TProcedure = procedure; 
TMethod =对象的过程;
TAnonMethod =引用过程;

这些都非常相似。在调用这三种类型中的每一种的实例方面,调用代码是相同的。



程序类型



TProcedure 程序类型您可以指定一个类型为 TProcedure 的变量:

 程序MyProcedure; 
begin
end;

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



方法指针



TMethod 方法指针 。这由对象的的存在指示。当您有一个类型为 TMethod 的变量时,您必须分配:


  1. 一个实例实例化对象的方法,或

  2. 一个类方法。

所以你可以分配这些:

 过程TMyClass.MyMethod; 
begin
end;

类程序TMyClass.MyClassMethod;
begin
end;

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



考虑以下代码:

  var 
instance1,instance2:TMyClass;
method1,method2:TMethod;
....
method1:= instance1.MyMethod;
method2:= instance2.MyMethod;

现在,虽然 method1 method2 指的是同一段代码,它们与不同的对象实例相关联。所以,如果我们调用

  method1(); 
method2();

我们正在调用 MyMethod 实例。该代码相当于:

  instance1.MyMethod(); 
instance2.MyMethod();

匿名方法



最后,我们来到匿名方法。这些是比过程类型和方法指针更通用的目的。您可以将以下任何一项分配给使用引用

  1. 一个简单的非面向对象的程序。

  2. 实例化类的一个实例方法。

  3. 一个类方法。 $ b
  4. 匿名方法

例如:

  var 
AnonMethod:TAnonMethod;
....
AnonMethod:= MyProcedure; // item 1 above
AnonMethod:= instance1.MyMethod; // item 2
AnonMethod:= TMyClass.MyClassMethod; // item 3

匿名方法,上面的第4项是在代码中声明的那些。例如:

  var 
AnonMethod:TAnonMethod;
....
AnonMethod:= procedure
begin
DoSomething;
结束

与过程类型和方法指针相比,匿名方法的最大好处是它们允许<一个href =http://docwiki.embarcadero.com/RADStudio/en/Anonymous_Methods_in_Delphi#Anonymous_Methods_Variable_Binding =noreferrer>变量捕获。例如考虑以下短程序来说明:

  {$ APPTYPE CONSOLE} 
程序VariableCapture;

类型
TMyFunc =函数引用(X:整数):整数;

函数MakeFunc(Y:Integer):TMyFunc;
begin
结果:= function(X:Integer):Integer
begin
结果:= X * Y;
结束
结束

var
func1,func2:TMyFunc;

begin
func1:= MakeFunc(3);
func2:= MakeFunc(-42);
Writeln(func1(4));
Writeln(func2(2));
Readln;
结束。

这有以下输出:

 
12
-84


What is the difference between

TFuncOfIntToString = reference to function(x: Integer): string; 

and

TFuncOfIntToString = function(x: Integer): string of object; 

I use the of object

解决方案

Let us consider the following three type declarations:

TProcedure = procedure;
TMethod = procedure of object;
TAnonMethod = reference to procedure;

These are all very similar to each other. In terms of calling instances of each of these three types, the calling code is identical. The differences arise in what can be assigned to variables of these types.

Procedural types

TProcedure is a procedural type. You can assign to a variable of type TProcedure something of this form:

procedure MyProcedure;
begin
end;

This is a non object-oriented procedure. You cannot assign an instance or class method to a TProcedure variable. However, you can assign a static class method to a TProcedure variable.

Method pointers

TMethod is a method pointer. This is indicated by the presence of of object. When you have a variable of type TMethod you must assign either:

  1. A instance method of an instantiated object, or
  2. A class method.

So you can assign either of these:

procedure TMyClass.MyMethod;
begin
end;

class procedure TMyClass.MyClassMethod;
begin
end;

The big difference between a procedural type and a method pointer is that the latter contains a reference to both code and data. A method pointer is often known as a two-pointer procedural type. A variable that contains a method pointer contains references to the code and the instance/class to call it on.

Consider the following code:

var
  instance1, instance2: TMyClass;
  method1, method2: TMethod;
....
method1 := instance1.MyMethod;
method2 := instance2.MyMethod;

Now, although method1 and method2 refer to the same piece of code, they are associated with different object instances. So, if we call

method1();
method2();

We are invoking MyMethod on the two distinct instances. That code is equivalent to:

instance1.MyMethod();
instance2.MyMethod();

Anonymous methods

Finally we come to anonymous methods. These are even more general purpose than procedural types and method pointers. You can assign any of the following to a variable defined using the reference to syntax:

  1. A plain non object-oriented procedure.
  2. An instance method of an instantiated class.
  3. A class method.
  4. An anonymous method.

For example:

var
  AnonMethod: TAnonMethod;
....
AnonMethod := MyProcedure;            // item 1 above
AnonMethod := instance1.MyMethod;     // item 2
AnonMethod := TMyClass.MyClassMethod; // item 3

Anonymous methods, item 4 above, are those declared in-line in your code. For example:

var
  AnonMethod: TAnonMethod;
....
AnonMethod := procedure
  begin
    DoSomething;
  end;

The biggest benefit of anonymous methods when compared to the procedural types and method pointers is that they allow for variable capture. For example consider the following short program to illustrate:

{$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.

This has the following output:

12
-84

这篇关于对象和引用有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆