Overloading an assignment operator for Object Pascal

What happens when an assignment operator is :=overloaded in Object Pascal? Basically, I mean what is first evaluated, and most importantly, how (if possible) I can change this order. Here is an example that bothers me:

I declare TMyClassas follows:

TMyClass = class
  private
    FSomeString: string;
    class var FInstanceList: TList;
  public
    function isValid: boolean;
    property SomeString: String write setSomeString;
  end;

The function isValidchecks MyObject for niland dangling pointers.

Now suppose I want to overload the statement :=to assign a string to TMyClass. I also want to check if the object that I am assigning to this line is a real object, and if not creating a new one, then:

operator :=(const anewString: string): TMyClass;
  begin
    if not(result.isValid) then
      result:= TMyObject.Create;
    result.SomeString:= aNewString;
  end;

In short, I was hoping the result would automatically hold the pointer to the object that I am assigning. But tests with the following:

procedure TForm1.TestButtonClick(Sender: TObject);
  var
    TestObject: TMyObject;
  begin
    TestObject:= TMyObject.Create;
    TestObject:= 'SomeString';
    TestObject.Free;
  end;

, result, TestObject :=.

, , , , - .

, , :=, - ? ( , .)

+4
2

, , . .

, := (LHS) ( Self, ), .

if not(result.isValid) then dangereous, undefined ( , , , , isValid . LHS.

, Self, isValid.

+4

Lazarus , Delphi . TValue.

:

  type
  TMyClass = class(TComponent)
  private
    FSomeString: string;
  published
    property SomeString: string read FSomeString write FSomeString;
  end;

(, TForm1).

  TForm1 = class(TForm)
  private
    FMyClass: TMyClass;
    function GetMyTypeString: TValue;
    procedure SetMyTypeString(const Value: TValue);
  public   
    property MyClass: TValue read GetMyTypeString write SetMyTypeString;
  end;

...

function TForm1.GetMyTypeString: TValue;
begin
  Result := FMyClass;
end;

procedure TForm1.SetMyTypeString(const Value: TValue);
begin
  if Value.Kind in [TTypeKind.tkChar, TTypeKind.tkUString,
    TTypeKind.tkString, TTypeKind.tkWChar, TTypeKind.tkWString]
  then
  begin
  if not Assigned(FMyClass) then
    FMyClass := TMyClass.Create(self);
  FMyClass.SomeString := Value.AsString;
  end else
    if Value.Kind = TTypeKind.tkClass then
      FMyClass := Value.AsType<TMyClass>;
end;

. , :=:

procedure TForm1.Button1Click(Sender: TObject);
begin
  MyClass := 'asd';
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  MyClass := TMyClass.Create(self);
end;

TMyClass:

procedure TForm1.Button3Click(Sender: TObject);
begin
  if Assigned(TMyClass(MyClass.AsObject)) then
    ShowMessage(TMyClass(MyClass.AsObject).SomeString)
  else
    ShowMessage('nil');
end;
+2

Source: https://habr.com/ru/post/1613975/


All Articles