TStream 使用了下面的代碼,強制子類必須implement兩個seek方法中至少一個
classes.pas 單元4904行@Delphi7
首先說明TStream有兩個seek方法
function Seek(Offset: Longint; Origin: Word): Longint; overload; virtual; //叫它seek1
function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; overload; virtual;//叫它seek2
看看如何實現的
function TStream.Seek(Offset: Longint; Origin: Word): Longint;
procedure RaiseException;
begin
raise EStreamError.CreateResFmt(@sSeekNotImplemented, [Classname]);
end;
type
//聲明了一個seek2樣式的函數類型
TSeek64 = function (const Offset: Int64; Origin: TSeekOrigin): Int64 of object;
var
//impl是子類的seek2方法,Base是TStream的seek2方法
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. }
//如果進入此函數,說seek1沒有被override,下面的任務就是驗證seek2必須被override;
Impl := Seek; //如果子類沒有實現seek,那麼impl就是seek2的方法(廬山中?)
//下面將ClassTStream將會是TStream的class類型,同時保證當前類是TStream的子類
ClassTStream := Self.ClassType;
while (ClassTStream <> nil) and (ClassTStream <> TStream) do
ClassTStream := ClassTStream.ClassParent;
if ClassTStream = nil then RaiseException;
//Base為TStream的seek2方法,這句的語法最有意思
Base := TStream(@ClassTStream).Seek;
//開始了,如果當前類的seek2方法和TStream的seek2方法代碼相同,那麼異常之
if TMethod(Impl).Code = TMethod(Base).Code then
RaiseException;
//能執行到這裡,表明seek2已經被override了,調用子類實現的seek2方法
Result := Seek(Int64(Offset), TSeekOrigin(Origin));
end;
function TStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
begin
{ Default implementation of 64 bit seek is to deflect to existing 32 bit seek.
Descendents that override 64 bit seek must not call this default implementation. }
//這裡就好解釋了,如果執行到這個方法,那麼說明本seek2未被override;,那麼seek1一定被override了,就調用seek1.
if (Offset < Low(Longint)) or (Offset > High(Longint)) then
raise ERangeError.CreateRes(@SRangeError);
Result := Seek(Longint(Offset), Ord(Origin));
end;
我剛開始看到 時候,還說怎麼回事,兩個overload的函數互相調用,沒有具體代碼,原來是要求子類必須實現其中一個,borland的工程師確實很牛!!!