Delphi属性stackoverflow错误

时间:2015-01-16 14:04:05

标签: delphi

我的物业类:

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

有趣的错误:

stackoverflow at xxxxxx

我正在学习Delphi中的属性。我创建了一个类,但它给出了一个错误。我无法理解,我的错误在哪里?

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

我无法设置属性值。

1 个答案:

答案 0 :(得分:5)

这是一个非终止递归。 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);