【问题标题】:How to dereference pointer to a class instance?如何取消引用指向类实例的指针?
【发布时间】:2014-10-16 08:25:10
【问题描述】:

问题摘要: 我指向一个类实例的指针,但是,当我尝试取消引用该指针并访问实例的属性时,我得到一个 EAccessViolation 异常,因为它取消引用“Nil ”。

我在单位范围内声明指针:

private
  CurrentRXFrame: ^TSXcpFrame;

每次我的程序接收到一个帧,指针都会更新为指向这个最新的帧:

procedure TfrmFoo.OnReceivingFrame(Sender: TObject);
var
  SXcpFrame: TSXcpFrame;
begin
  SXcpFrame := TSXcpFrame.Create();
  CurrentRXFrame := @SXcpFrame;

我尝试在同一单元中的某个其他例程中取消引用指针,但得到一个异常:

// `FrameBytes` is merely a dynamic array of type "Byte".
PrintMsg(IntToHex(CurrentRXFrame^.FrameBytes[0], 2)); 

例外:

raise exception class EAccessViolation with message 'Access violation at address 004DD1FE [...] Read of address 00000010.

如果我在此行之前设置断点,则相关变量的评估结果如下:

CurrentRXFrame := $18FD10
CurrentRXFrame^ := nil
CurrentRXFrame^.FrameBytes := Inaccessible value

问题:如何通过指针访问TSxcpFrame 类实例的属性?

【问题讨论】:

  • 你获取了一个局部变量的地址。该地址在声明变量的函数结束之前一直有效。

标签: delphi pointers delphi-7 dereference


【解决方案1】:

问题是你有一个指向变量的指针,如果它是一个局部变量,它很快就会失效。

但没有必要这样做。 类实例引用已经是指针,所以你可以(或者,IMO,应该)这样做:

var
  CurrentRXFrame: TSXcpFrame;

及以后:

  SXcpFrame := TSXcpFame.Create;
  CurrentRXFrame := SXcpFrame;

当然还有:

  PrintMsg(IntToHex(CurrentRXFrame.FrameBytes[0], 2));

请注意SXcpFrameCurrentRXFrame 不是结构,它们只是对一个的引用,因此在赋值时,不会复制数据,仅复制引用。具有数据的实例的结构位于堆上。赋值后,两个引用引用相同的数据。

【讨论】:

  • 太棒了,先生!这样可行。非常感谢你。保存实例的变量已经是指针,这一点非常重要。
  • 我推荐阅读Delphi Language Guide,它是内置帮助的一部分,但也可以在网上找到。
  • 该链接适用于 XE7,而不是 Delphi 7。内置帮助仅供参考。我也有“Object Pascal 语言指南”文档,但我在那里(或网络上的任何地方)没有发现任何关于指向类实例的指针。
  • 好的,我找到了 D7LG。在“类和对象”一章的“类类型”一节中,它说:“类类型的变量实际上是一个引用对象的指针。因此,多个变量可以引用同一个对象。像其他指针一样,类-type 变量可以保存值 nil。但您不必显式取消引用类类型变量来访问它指向的对象。"
  • XE7 语言指南适用于 D7。变化很少。并且所有版本的语言指南都清楚地描述了这个问题。语言指南写得很好。我把它推荐给你。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-04
  • 2019-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-25
相关资源
最近更新 更多