4

我有一段简单的代码,可以在 Delphi XE2 中编译,但不能在 XE3 中编译,我不知道为什么。我已将有问题的代码减少到一点点,并想知道 Delphi 认为它有什么问题。尝试在 Delphi XE 2 中编译包含该单元的项目工作正常,但在 Delphi XE3(试用版)中,它给出“[dcc32 Error] AffineTransform.pas(26): E2382 Cannot call constructors using instance variables”。我在这里知道的唯一“古怪”的事情是使用老式的“对象”类型,其中构造函数与真实对象(基于 TObject 的类实例)中的构造函数并不完全相同。

如果我将此对象中的“构造函数”替换为“过程”,那么它可以编译,但是为什么会这样,在我的代码中这是一个可以做的改变吗,即它是否对功能?

unit AffineTransform;

interface

type
  { Rectangular area. }
  TCoordRect = object
  public
    Left, Top, Right, Bottom: Real;
    constructor CreatePos(ALeft, ATop, ARight, ABottom: Real);
    procedure   Include(AX, AY: Real);
  end;

implementation

constructor TCoordRect.CreatePos(ALeft, ATop, ARight, ABottom: Real);
begin
  Left := ALeft;
  Top := ATop;
  Right := ARight;
  Bottom := ABottom;
end;

procedure TCoordRect.Include(AX, AY: Real);
begin
  CreatePos(AX, AY, AX, AY)
end;

end.
4

2 回答 2

7

对于这种传统的 Turbo Pascal 风格object,关键字确实没有任何意义constructor。尽管object构造函数确实有一些特殊处理,但这里绝对不需要。这里所拥有的不过是record一些方法。

XE3 编译器已更改,因此它不再允许您在Self实例方法内部调用构造函数。class和都是这种情况object。我没有看到任何文档说明为什么要进行此更改。毫无疑问,它会及时渗出。

您的直接解决方案是替换constructorprocedure. record从长远来看,把它变成 a而不是a 是有意义的object


我还建议您将该方法的名称更改为Initialize. 一些图书馆设计师似乎选择在他们的记录上使用Create和方法。Free这导致大量的代码是这样编写的:

ctx := TRttiContext.Create;
try
  ....
finally
  ctx.Free;
end;

事实上,所有这些代码都是虚假的,可以简单地删除!TRttiContext变量会自动初始化。

这种设计也为喜欢使用的 Delphi 编码人员设置了一个巨大的Heffalump 陷阱FreeAndNil。传递记录会FreeAndNil导致一些有趣的烟花!

于 2012-10-18T14:08:24.627 回答
6

我有一段简单的代码,可以在 Delphi XE2 中编译,但不能在 XE3 中编译,我不知道为什么。

您试图在已经实例化和初始化的实例的方法内调用构造函数。编译器不再允许这样做。更具体地说,这段代码:

procedure TCoordRect.Include(AX, AY: Real); 
begin 
  CreatePos(AX, AY, AX, AY) 
end; 

与此代码相同:

procedure TCoordRect.Include(AX, AY: Real); 
begin 
  Self.CreatePos(AX, AY, AX, AY) 
end; 

而且你不能再在Self变量上调用构造函数了。为什么?IIRC,它与编译器正在向支持移动开发的转变有关。

于 2012-10-18T17:28:08.220 回答