初探Object Pascal的类(七)

关于Self

所有的类都有一个隐含的字段叫Self,在内存中Self是一个指向类实例的指针

首先我们来看看,如果Self不是隐含字段的话,那么TMyRec类到底是一个什么样子:

  TMyRect = class
  private
    Self: TMyRect; { Self隐含字段}
    Left: Integer;
    Top: Integer;
    Right: Integer;
    Bottom: Integer;
    Text: PChar; 
  public
    function GetWidth: Integer;
    function GetHeight: Integer;
    procedure SetRect(ALeft, ATop, ARight, ABottom: Integer);
    constructor Create;  
    constructor CreateVal(ALeft, ATop, ARight, ABottom: Integer);
    destructor Destroy; override; 
  end;

对于编译器来说,这就是实际TMyRect类的样子。当类对象建立时,Self指针会自动初始化为内存中类的地址:

  Rect1 := TMyRect.CreateVal(100, 100, 500, 500);
  { 现在Rect1和Rect1.Self具有相同的值,因为两者都包含对象在内存中的地址}

Self到底是什么意思?

记住每个类实例都会得到各自的类字段拷贝,但所有类实例享有类的相同方法集(没有必要为每个实例都复制代码),这样编译器怎么识别哪个实例调用哪个方法呢?所有类方法都有一个隐含Self参数,为了声明这一点,假设有一个TMyRect类的函数叫GetWidth,其表现如下:

function TMyRect.GetWidth: Integer;
begin
  Result := Right - Left;
end;

对大家来说,这个就是这个样子的,但是对于编译器来说,其表现形式应如下:

function TMyRect.GetWidth: Integer;
begin
  Result := Self.Right - Self.Left;
end;

看来Self是在幕后工作的,我们不必担心其是怎样发生的只要只奥它发生了就行。

Caution

绝不要修改Self指针,可以用它把一个指向类的指针传送给其他方法,或者作为构造其他类的参数,但不要改变它的值,要学会把Self当作一个只读变量。

Note

前面讨论过类方法(class method)不能存取类字段,这正是因为类方法没有一个隐含的Self参数,而普通的方法可以存取类字段。如果没有Self,普通方法就不能存取类字段。

现在还不要太担心怎样使用Self,当开始使用VCL时,就需要在Delphi应用程序中用Self,这样很快就会明白它的用法。

posted on 2011-12-30 02:15  pchmonster  阅读(849)  评论(0编辑  收藏  举报

导航