gpt4 book ai didi

oop - Lazarus/Delphi-Create vs TSomeClass.Create内部构造函数-为什么这会引起麻烦?

转载 作者:行者123 更新时间:2023-12-03 19:46:31 27 4
gpt4 key购买 nike

突出

此构造函数:

constructor TCoords.Create(const AX, AY: Integer);
begin
TCoords.Create(Point(AX, AY));
end;


已确认Linux Lazarus 2和Windows Delphi XE6均出现故障。

这可能是错误吗?



我是Lazarus / Delphi中OOP的新手,请原谅新手错误。谢谢。

我似乎无法理解为什么下面的Lazarus /(类似于Delphi)自定义序列非常基本,一个对象将无法工作。我已经尝试调试了几个小时,从那时起我发现:

什么有效:

调用一个没有参数的构造函数,并直接使用TPoint参数调用一个构造函数。

什么不是:

称之为:

constructor Create(const AX, AY: Integer);


但是,我发现这是可行的-但前提是在构造函数中不带其类名的情况下调用它。为什么会引起麻烦?



声明书

// WORKS - this creates instance of TCoords initialized to PointOutOfReach
constructor Create; reintroduce;
// WORKS - this creates instance of TCoords initialized to user coordinates
constructor Create(const ACoords: TPoint);
// DOES NOT WORK, strangely returns Point(0, 0), if called with class name
// WORKS only if called without class name - confusing or error on my side?
constructor Create(const AX, AY: Integer);




来电

// OK - WORKING
NewCoords := TCoords.Create;
NewCoords.X:=12;
NewCoords.Y:=120;
ShowMessage(NewCoords.X.ToString + ' : ' + NewCoords.Y.ToString);
NewCoords.Free;

// OK - WORKING
NewCoords := TCoords.Create(Point(12, 120));
ShowMessage(NewCoords.X.ToString + ' : ' + NewCoords.Y.ToString);
NewCoords.Free;

// NOT WORKING as expected
NewCoords := TCoords.Create(12, 120);
ShowMessage(NewCoords.X.ToString + ' : ' + NewCoords.Y.ToString);
NewCoords.Free;




具有TCoords对象定义的Coords单元

unit Coords;

{$mode objfpc}{$H+}

interface

uses
Classes;

type
// Flexible X,Y coordinates object.
TCoords = class(TObject)

// these declarations are accessible within this unit only
private
// this is the variable we are working with
FCoords: TPoint;
// property for this function is unnecessary, but I like it as it is
function IsInitialized: Boolean;

// these declarations are accessible to all
public
// this creates instance of TCoords initialized to PointOutOfReach
constructor Create; reintroduce;
// this creates instance of TCoords initialized to user coordinates
constructor Create(const ACoords: TPoint);

// THIS ONE DOES NOT WORK, strangely returns Point(0, 0)
constructor Create(const AX, AY: Integer);

// this indicates if instance was initialized or not by the user
property Initialized: Boolean read IsInitialized;
// this works directly with private FCoords variable storing coordinates
property P: TPoint read FCoords write FCoords;
// these two are shortcuts for X,Y coordinates' direct access
property X: Integer read FCoords.X write FCoords.X;
property Y: Integer read FCoords.Y write FCoords.Y;

end;

implementation

var
// this gets initialized when loading this unit
PointOutOfReach: TPoint;

constructor TCoords.Create;
begin
// this is the same as `inherited`, but I like to be explicit
inherited Create;
// since called without argument, we have to ensure, there is some nonsense
FCoords := PointOutOfReach;
end;

constructor TCoords.Create(const ACoords: TPoint);
begin
// this is the same as `Create`, but I like to be explicit
TCoords.Create;
// in the previous mandatory call we have initialized FCoords already
// but to PointOutOfReach; here we overwrite it with user coordinates
FCoords := ACoords;
end;

constructor TCoords.Create(const AX, AY: Integer);
begin
// this is the same as `Create(TPoint)`, but I like to be explicit
// TCoords.Create(Point(AX, AY));

// Why can't I call the above, shouldn't it be the very same?
Create(Point(AX, AY));
end;

function TCoords.IsInitialized: Boolean;
begin
// this returns True in case FCoords has been initialized
// initialized means here for the FCoords point to be different from PointOutOfReach
// achieved either by calling `Create(APoint)`, or later overwriting PointOutOfReach
Result := FCoords <> PointOutOfReach;
end;

initialization

// initialize PointOutOfReach to "impossible" coordinates when loading unit
PointOutOfReach := Point(MAXINT, MAXINT);

end.




在此先感谢您,我自己似乎看不出两​​者之间的区别。



已纠正主要错误-不变

构造函数声明中缺少 overload;的问题已得到纠正。遗憾的是,仍然从最后一个构造函数获得0,0坐标。

最佳答案

David Heffernan在评论中指出了我的方法不起作用的原因,请允许我引用:


TCoords.Create(Point(AX, AY))创建一个新实例。在构造函数中执行此操作时,现在有两个实例。将其替换为Create(Point(AX, AY))


谢谢您的解释!



如果甚至解决了,我认为更好的方法将是不链接那些constructor



应用此规则可以正常工作,使用未链接的构造函数的代码段:



constructor TCoords.Create;
begin
inherited Create;
// since called without argument, we have to ensure,
// there are some corner-case coordinates, so that we can
// differentiate between a [0:0] and uninitialized state
FCoords := PointOutOfReach;
end;

constructor TCoords.Create(const ACoords: TPoint);
begin
inherited Create;
FCoords := ACoords;
end;

constructor TCoords.Create(const AX, AY: Integer);
begin
inherited Create;
FCoords := Point(AX, AY);
end;




PS:为了使代码正常工作,到目前为止,我认为没有必要像 Nasreddine Galfoutanswer中那样应用“ setter”。

关于oop - Lazarus/Delphi-Create vs TSomeClass.Create内部构造函数-为什么这会引起麻烦?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56198611/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com