Delphi属性stackoverflow错误

Dau*_*evy 7 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.
Run Code Online (Sandbox Code Playgroud)

分配:

objSubImg.width:= imgOverview.width;
objSubImg.height:= imgOverview.heigh
Run Code Online (Sandbox Code Playgroud)

有趣的错误:

stackoverflow at xxxxxx
Run Code Online (Sandbox Code Playgroud)

我正在学习德尔福的房产.我创建了一个类,但它给出了一个错误.我无法理解,我的错误在哪里?

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

我无法设置属性值.

Dav*_*nan 5

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

function TSubImage.getHeight: Integer;
begin
  Result := height;
end;
Run Code Online (Sandbox Code Playgroud)

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

function TSubImage.getHeight: Integer;
begin
  Result := getHeight;
end;
Run Code Online (Sandbox Code Playgroud)

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

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

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;
Run Code Online (Sandbox Code Playgroud)

然后获取并设置值:

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

procedure TSubImage.setHeight(const Value: Integer);
begin
  FHeight:= Value;
end;
Run Code Online (Sandbox Code Playgroud)

对于其他财产也是如此.

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

property width: Integer read FWidth write FWidth;
property height: Integer read FHeight write FHeight;
Run Code Online (Sandbox Code Playgroud)

但我想你知道并正在探索getter/setter函数是如何工作的.

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

h := obj.Height;
obj.Height := h*2;
Run Code Online (Sandbox Code Playgroud)

h := obj.GetHeight;
obj.SetHeight(h*2);
Run Code Online (Sandbox Code Playgroud)