对象和引用有什么区别? [英] What is the difference between of object and reference to?
问题描述
TFuncOfIntToString =引用函数(x:Integer):string;
和
TFuncOfIntToString = function(x:Integer):对象的字符串;
我使用对象
让我们考虑以下三种类型的声明:
TProcedure = procedure;
TMethod =对象的过程;
TAnonMethod =引用过程;
这些都非常相似。在调用这三种类型中的每一种的实例方面,调用代码是相同的。
程序类型
TProcedure
是程序类型您可以指定一个类型为 TProcedure
的变量:
程序MyProcedure;
begin
end;
这是一个非面向对象的过程。您不能将实例或类方法分配给 TProcedure
变量。但是,您可以将静态类方法分配给 TProcedure
变量
方法指针
TMethod
是方法指针 。这由对象的的存在指示。当您有一个类型为
TMethod
的变量时,您必须分配:
- 一个实例实例化对象的方法,或
- 一个类方法。
所以你可以分配这些:
过程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();
匿名方法
最后,我们来到匿名方法。这些是比过程类型和方法指针更通用的目的。您可以将以下任何一项分配给使用
引用
- 一个简单的非面向对象的程序。
- 实例化类的一个实例方法。
- 一个类方法。 $ b
- 匿名方法
例如:
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:
- A instance method of an instantiated object, or
- 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:
- A plain non object-oriented procedure.
- An instance method of an instantiated class.
- A class method.
- 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屋!