xe8 programming language delphi oop language-features self delphi-prism

programming - ¿Por qué es auto asignable en Delphi?



delphi xe8 wiki (5)

Este código en una aplicación GUI compila y ejecuta:

procedure TForm1.Button1Click(Sender: TObject); begin Self := TForm1.Create(Owner); end;

(probado con Delphi 6 y 2009)

  • ¿Por qué es autoescribible y no de solo lectura?
  • ¿En qué situaciones podría ser útil?

Editar:

  • ¿Es esto también posible en Delphi Prism? (Creo que sí lo es, ver here )

Actualización: aplicaciones / bibliotecas de Delphi que hacen uso de la auto asignación:


A veces, cuando desea optimizar un método en la medida en que puede llevarlo (sin tener que recurrir al ensamblaje), ''Self'' puede ser (ab) usado como una variable ''libre''; podría significar la diferencia entre usar stack y utilizando registros.

Claro, lo más probable es que el contenido de la pila ya esté presente en la memoria caché de la CPU, por lo que debería ser de acceso rápido, pero los registros son aún más rápidos.

Como una nota al margen: todavía me faltan los días en que estaba programando en el Motorola 68000 de Amiga y tuve el lujo de tener 16 registros de datos y 16 direcciones ... No puedo creer que el mundo haya optado por los 4 registros De la línea de procesadores 80x86!

Y como nota final, elijo usar Yo a veces, ya que el optimizador de Delphi, bueno, en realidad no lo está optimizando . (Por lo menos, palidece en comparación con el engaño que se puede encontrar en los diversos optimizadores de LLVM, por ejemplo). En mi humilde opinión, y por supuesto en YMMV.


Asignarse a uno mismo es tan ilógico e inútil que esta "característica" es probablemente un descuido. Y al igual que con las constantes asignables, no siempre es fácil corregir estos problemas.

El consejo simple aquí es: no lo hagas.


En realidad, "Self" es solo una referencia de nombre a un lugar en la pila que almacena la dirección que apunta al objeto en el montón. Es posible forzar solo lectura en esta variable, aparentemente el diseñador decidió no hacerlo. Creo que la decisión es arbitraria.

No se puede ver ningún caso en el que esto sea útil, que simplemente cambie un valor en la pila. Además, cambiar este valor puede ser peligroso ya que no hay garantía de que el comportamiento del código al que se refieren los miembros de la instancia sea coherente en todas las versiones del compilador.

Actualizado: En respuesta al comentario de PatrickvL

La "variable" "Yo" no está en la pila (que yo sepa, nunca lo está); En su lugar, el valor se coloca en un registro (EAX para ser exacto) justo antes de que se realice una llamada a cualquier método de objeto. -

No, Self tiene una dirección real en la memoria. Intenta este código para ver por ti mismo.

procedure TForm1.Button1Click(Sender: TObject); begin ShowMessage(IntToStr(Integer(@Self))); end; procedure TForm1.Button2Click(Sender: TObject); var newform: TForm; p: ^Integer; begin Self.Caption := ''TheOriginal''; newform := TForm.Create(nil); try newform.Caption := ''TheNewOne''; // The following two lines is, technically, the same as // Self := newform; p := Pointer(@Self); p^ := Integer(newform); ShowMessage(Self.Caption); // This will show ''TheNewOne'' instead of ''TheOriginal'' finally Self.Free; // Relax, this will free TheNewOne rather than TheOriginal end; end;


Eso no es tan malo como podría ser. Acabo de probarlo en Delphi 2009, y parece que, si bien el parámetro Self no usa semántica constante , lo que parece que implica que debería, tampoco usa la semántica var , por lo que puede cambiarlo todo desea dentro de su método sin perder realmente la referencia que la persona que llama tiene para su objeto. Eso sería algo muy malo.

En cuanto al motivo, una de las dos respuestas. Ya sea un simple descuido, o lo que Marco sugirió: para permitirle pasar Self a un parámetro var .


Tal vez para permitir pasar a const o var parámetros?

Podría ser un artefacto, ya que el sistema no tiene yo en ninguna parte a la izquierda de: = signo.