delphi - reynosa - ¿Cuál es la diferencia entre objeto y referencia?
delphi technologies mexico (2)
Consideremos las siguientes tres declaraciones de tipo:
TProcedure = procedure;
TMethod = procedure of object;
TAnonMethod = reference to procedure;
Todos estos son muy similares entre sí. En términos de llamadas de instancias de cada uno de estos tres tipos, el código de llamada es idéntico. Las diferencias surgen en lo que se puede asignar a las variables de estos tipos.
Tipos de procedimiento
TProcedure
es un tipo de procedimiento . Puede asignar a una variable de tipo TProcedure
algo de esta forma:
procedure MyProcedure;
begin
end;
Este es un procedimiento no orientado a objetos. No puede asignar una instancia o método de clase a una variable TProcedure
. Sin embargo, puede asignar un método de clase estática a una variable TProcedure
.
Punteros del método
TMethod
es un puntero de método . Esto está indicado por la presencia of object
. Cuando tiene una variable de tipo TMethod
, debe asignar cualquiera:
- Un método de instancia de un objeto instanciado, o
- Un método de clase.
Entonces puedes asignar cualquiera de estos:
procedure TMyClass.MyMethod;
begin
end;
class procedure TMyClass.MyClassMethod;
begin
end;
La gran diferencia entre un tipo de procedimiento y un puntero de método es que este último contiene una referencia tanto al código como a los datos. Un puntero de método a menudo se conoce como un tipo de procedimiento de dos punteros. Una variable que contiene un puntero de método contiene referencias al código y la instancia / clase para invocarlo.
Considera el siguiente código:
var
instance1, instance2: TMyClass;
method1, method2: TMethod;
....
method1 := instance1.MyMethod;
method2 := instance2.MyMethod;
Ahora, aunque method1
y method2
referencia a la misma pieza de código, están asociados con diferentes instancias de objetos. Entonces, si llamamos
method1();
method2();
Estamos invocando MyMethod
en las dos instancias distintas. Ese código es equivalente a:
instance1.MyMethod();
instance2.MyMethod();
Métodos anónimos
Finalmente llegamos a métodos anónimos . Estos son incluso más generales que los tipos de procedimientos y punteros de método. Puede asignar cualquiera de los siguientes a una variable definida utilizando la reference to
sintaxis:
- Un procedimiento simple no orientado a objetos.
- Un método de instancia de una clase instanciada.
- Un método de clase.
- Un método anónimo.
Por ejemplo:
var
AnonMethod: TAnonMethod;
....
AnonMethod := MyProcedure; // item 1 above
AnonMethod := instance1.MyMethod; // item 2
AnonMethod := TMyClass.MyClassMethod; // item 3
Los métodos anónimos, elemento 4 anterior, son aquellos declarados en línea en su código. Por ejemplo:
var
AnonMethod: TAnonMethod;
....
AnonMethod := procedure
begin
DoSomething;
end;
El mayor beneficio de los métodos anónimos en comparación con los tipos de procedimientos y punteros de método es que permiten la captura variable . Por ejemplo, considere el siguiente programa breve para ilustrar:
{$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.
Esto tiene el siguiente resultado:
12 -84
Cuál es la diferencia entre
TFuncOfIntToString = reference to function(x: Integer): string;
y
TFuncOfIntToString = function(x: Integer): string of object;
Yo uso el objeto
El primero es el método anónimo , el segundo es el method ordinario.