在TStream 类当中seek方法如下function TStream.Seek(Offset: Longint; Origin: Word): Longint;  procedure RaiseException;
  begin
    raise EStreamError.CreateResFmt(@sSeekNotImplemented, [Classname]);
  end;type
  TSeek64 = function (const Offset: Int64; Origin: TSeekOrigin): Int64 of object;
var
  Impl: TSeek64;
  Base: TSeek64;
  ClassTStream: TClass;
begin
{ Deflect 32 seek requests to the 64 bit seek, if 64 bit is implemented.
  No existing TStream classes should call this method, since it was originally
  abstract.  Descendent classes MUST implement at least one of either
  the 32 bit or the 64 bit version, and must not call the inherited
  default implementation. }
  Impl := Seek;
  ClassTStream := Self.ClassType;
  while (ClassTStream <> nil) and (ClassTStream <> TStream) do
    ClassTStream := ClassTStream.ClassParent;
  if ClassTStream = nil then RaiseException;
  Base := TStream(@ClassTStream).Seek;
  if TMethod(Impl).Code = TMethod(Base).Code then
    RaiseException;
  Result := Seek(Int64(Offset), TSeekOrigin(Origin));
end;
    这一句
    Base := TStream(@ClassTStream).Seek;
    ClassTStream声明为TCLass类型,我理解为指向本类vmt表的指针,但类型转换是为什么前面要加一个@符号呢 
    我另外实验了一下
    procedure TForm1.Button6Click(Sender: TObject);
    type
    TShow=procedure () of object;
    var
    aClass:TClass;
    aObj:TMYStream;
    aProc:TShow;
   begin
    aObj:=TMYStream.Create;
    aClass:=aObj.ClassType;
    TMyStream(aClass).ShowStr2;<---
    TMyStream(@aClass).ShowStr2;<---
  end
   同样是类型转换,你加@和不加@都可以成功     谁能给个权威的解释不? 加@和不加@有什么影响没?     

解决方案 »

  1.   

    @运算符是“取址”运算。表示取出内存地址值。
    对象引用类型的变量,实际上它代表的是一个内存地址,也就是引用所指对象的内存入口地址。
    对于对象引用来讲,直接使用 引用变量,其实就是相当于使用这个类的入口地址。  TMyStream(aClass).ShowStr2;<--- 这儿是进行对象类型的转换(编译器负责取内存地址),实际上就是对内存入口地址的转换。
      TMyStream(@aClass).ShowStr2;<---这儿你先取址,其实是你手工进行了取址操作,然后再转换成目标对象的入口地址。
    ***** 事实上,简单些讲,不论是什么类型,我都理解为是一块内存块。对象变量就理解为内存块的入口地址*****
    目标类名的主要作用是决定这个指针的寻址范围。