Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么Delphi XE3给出;E2382无法使用实例变量";?调用构造函数;?_Delphi_Object_Constructor - Fatal编程技术网

为什么Delphi XE3给出;E2382无法使用实例变量";?调用构造函数;?

为什么Delphi XE3给出;E2382无法使用实例变量";?调用构造函数;?,delphi,object,constructor,Delphi,Object,Constructor,我有一段简单的代码,可以用Delphi XE2编译,但不能用XE3编译,我不知道为什么。我已经将有问题的代码减少到一点点,并且想知道Delphi认为它有什么问题。尝试在Delphi XE 2中编译包含此单元的项目效果很好,但在Delphi XE 3(试用版)中,它会给出“[dcc32 Error]AffineTransform.pas(26):E2382无法使用实例变量调用构造函数”。我在这里所知道的唯一“古怪”的事情是使用了老式的“对象”类型,其中构造函数实际上与真实对象(基于TObject的

我有一段简单的代码,可以用Delphi XE2编译,但不能用XE3编译,我不知道为什么。我已经将有问题的代码减少到一点点,并且想知道Delphi认为它有什么问题。尝试在Delphi XE 2中编译包含此单元的项目效果很好,但在Delphi XE 3(试用版)中,它会给出“[dcc32 Error]AffineTransform.pas(26):E2382无法使用实例变量调用构造函数”。我在这里所知道的唯一“古怪”的事情是使用了老式的“对象”类型,其中构造函数实际上与真实对象(基于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.

对于这个传统的turbopascal样式
对象
,关键字
构造函数
实际上没有任何意义。虽然
对象
构造函数确实有一些特殊的处理,但这里绝对没有必要这样做。这里所拥有的不过是一个带有一些方法的
记录

XE3编译器已更改,因此不再允许您在实例方法中调用
Self
上的构造函数。这是
对象
的情况。我还没有看到任何文件说明为什么会做出这样的改变。毫无疑问,它会及时渗透出去

您的直接解决方案是将
构造函数
替换为
过程
。从长远来看,将其转换为
记录
而不是
对象
是有意义的


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

ctx := TRttiContext.Create;
try
  ....
finally
  ctx.Free;
end;
事实上,所有这些代码都是假的,可以简单地删除!
TRttiContext
变量将自动初始化自身

这种设计也为喜欢使用
FreeAndNil
的德尔福编码器群体树立了一个巨人。将记录传递到
FreeAndNil
会引发一些有趣的焰火

我有一段简单的代码,可以用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; 
与此代码相同:

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,这与编译器正在向支持移动开发的方向转变有关。

为什么要在传统的Turbo Pascal对象上实现构造函数?这应该是一个过程,它应该被称为
Initialize
@LaKraven没有继承的Create。这是
对象
,而不是
。没有发现它,@DavidHeffernan。干杯这不是我最初的代码,只是一些落入我手中的东西,所以我不能说出作者最初的动机。据我所知,Create和CreatePos方法的目的只是初始化结构,所以我猜调用它们构造函数只是为了让它们作为初始化方法从代码中脱颖而出。但由于我不确定,这基本上就是我在这里要问的,也就是说,“构造函数”和“过程”在功能上有什么区别,为什么我不应该仅仅改变术语?另外,好奇的是,为什么XE3给出错误而XE2not?那么,当您有多个构造函数(具有不同的名称)并且希望从一个构造函数内部调用另一个构造函数时,这是如何实现的呢。我真的希望这仍然是允许的?应该是,毕竟它们都是构造函数,所以类方法而不是实例方法…@marjan是的,这是允许的。+1表示“heffatlump Trap”。我现在急切地期待着以某种方式将其写进一份报告……:)谢谢你的回答!你的评论给我留下了一些最后的小疑问:“虽然对象构造函数确实有一些特殊处理,但这里绝对没有必要。”因为我在这里展示的是原始代码的简化版本,只是为了重现错误,所以我想知道这“一些特殊处理”可能是什么,以防它与我的原始代码仍有某种关联。特殊处理是调用System.pas中的
\u ObjSetup
,在对象中设置VMT指针。由于您的对象只不过是一个普通的旧记录,并且没有任何虚拟方法,所以这不适用于这里。+1是关于“它与编译器正在向支持移动开发的方向转变有关”的评论。这是我得到的关于原因的最佳信息。当然,如果有更好的信息就好了,而且Delphi文档中没有关于这个错误消息的内容,所以这也很好。但感谢你的付出我想雷米指的是正在开发的下一代编译器。Emba正在清理当前编译器中的一些奇怪之处,并试图尽可能合理地将传统编译器与下一代编译器对齐。