程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> borland工程師如何保證父類(TStream)的兩個overload的seek,至少

borland工程師如何保證父類(TStream)的兩個overload的seek,至少

編輯:Delphi
 

  TStream 使用了下面的代碼,強制子類必須implement兩個seek方法中至少一個
  

  classes.pas 單元4904行@Delphi7

  首先說明TStream有兩個seek方法

  function Seek(OffsetLongintOriginWord): Longintoverloadvirtual; //叫它seek1
  function Seek(const OffsetInt64OriginTSeekOrigin): Int64overloadvirtual;//叫它seek2
  

  看看如何實現的

  function TStream.Seek(OffsetLongintOriginWord): Longint;
  
    procedure RaiseException;
    begin
      raise EStreamError.CreateResFmt(@sSeekNotImplemented, [Classname]);
    end;
  
  type 

     //聲明了一個seek2樣式的函數類型
    TSeek64 = function (const OffsetInt64OriginTSeekOrigin): Int64 of object;
  var 

     //impl是子類的seek2方法,Base是TStream的seek2方法

    ImplTSeek64;
    BaseTSeek64;
    ClassTStreamTClass;
  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 <> niland (ClassTStream <> TStreamdo
      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 OffsetInt64OriginTSeekOrigin): 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的工程師確實很牛!!!
  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved