Delphi 属性 stackoverflow 错误

Delphi property stackoverflow error

我的属性Class:

unit SubImage;

interface

type
TSubImage = class
private
  { private declarations }
  function getHeight: Integer;
  function getWidth: Integer;
  procedure setHeight(const Value: Integer);
  procedure setWidth(const Value: Integer);
protected
  { protected declarations }
public
  { public declarations }
  property width : Integer read getWidth write setWidth;
  property height : Integer read getHeight write setHeight;
published
  { published declarations }
end;
implementation

{ TSubImage }

function TSubImage.getHeight: Integer;
begin
  Result:= height;
end;

function TSubImage.getWidth: Integer;
begin
  Result:= width;
end;

procedure TSubImage.setHeight(const Value: Integer);
begin
  height:= Value;
end;

procedure TSubImage.setWidth(const Value: Integer);
begin
  width:= Value;
end;

end.

作业:

objSubImg.width:= imgOverview.width;
objSubImg.height:= imgOverview.heigh

有趣的错误:

Whosebug at xxxxxx

我正在学习 Delphi 中的属性。我创建了一个 class,但它给出了一个错误。我没看懂,我哪里错了?

我也不明白为什么我们使用 属性 而不是 setter/getter 方法。无论如何有人可以帮助我,我该如何修复这段代码?

我无法设置 属性 值。

这是一个非终止递归。 getter 看起来像这样:

function TSubImage.getHeight: Integer;
begin
  Result := height;
end;

但是height就是属性。所以编译器将其重写为:

function TSubImage.getHeight: Integer;
begin
  Result := getHeight;
end;

这是一个非终止递归。因此堆栈溢出。

您需要声明字段来存储值:

type
  TSubImage = class
  private
    FHeight: Integer;
    FWidth: Integer;
    function getHeight: Integer;
    function getWidth: Integer;
    procedure setHeight(const Value: Integer);
    procedure setWidth(const Value: Integer);
  public
    property width: Integer read getWidth write setWidth;
    property height: Integer read getHeight write setHeight;
  end;

然后获取并设置值:

function TSubImage.getHeight: Integer;
begin
  Result:= FHeight;
end;

procedure TSubImage.setHeight(const Value: Integer);
begin
  FHeight:= Value;
end;

另一个属性也是如此。

在这个简单的示例中,您不需要使用 getter 和 setter 函数。您可以这样声明属性:

property width: Integer read FWidth write FWidth;
property height: Integer read FHeight write FHeight;

但我想您知道这一点并且正在探索 getter/setter 函数的工作原理。

至于为什么我们使用属性而不是 getter 和 setter 函数,归结为代码的清晰度和可读性。您可以使用 getter 和 setter 函数替换属性。毕竟,这就是编译器所做的一切。但是这样写往往更清楚:

h := obj.Height;
obj.Height := h*2;

h := obj.GetHeight;
obj.SetHeight(h*2);