Why is Self assignable in Delphi?

后端 未结 5 913
星月不相逢
星月不相逢 2021-01-04 02:17

This code in a GUI application compiles and runs:

procedure TForm1.Button1Click(Sender: TObject);
begin
  Self := TForm1.Create(Owner);
end;
<
5条回答
  •  无人及你
    2021-01-04 02:42

    In reality, "Self" is just a name reference to a place on the stack that store address pointing to object in the heap. Forcing read-only on this variable is possible, apparently the designer decided not to. I believe the decision is arbitrary.

    Can't see any case where this is useful, that'd merely change a value in stack. Also, changing this value can be dangerous as there is no guarantee that the behavior of the code that reference instance's member will be consistence across compiler versions.

    Updated: In response to PatrickvL comment

    The 'variable' "Self" is not on the stack (to my knowledge, it never is); Instead it's value is put in a register (EAX to be exact) just before a call to any object method is made. –

    Nope, Self has actual address on the memory. Try this code to see for yourself.

    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;
    

提交回复
热议问题