線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:2103
推到 Plurk!
推到 Facebook!

如何改寫TMemoryStream的Size Property?

尚未結案
BGman
初階會員


發表:28
回覆:85
積分:42
註冊:2003-01-10

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-03-03 17:26:57 IP:211.22.xxx.xxx 未訂閱
我要改寫繼承自TMemoryStream 的一個 Property Size 遇到一些障礙,希望各位高手可以指點迷津! TMPHMemoryStream = class(TMemoryStream) function GetSize: int64;不打算Override procedure SetSize(NewSize: longint); override; property Size: int64 read GetSize write SetSize; 問題一、為何不能改寫成參數為int64 的函式 SetSize(NewSize: int64); 卻出現警告[Warning] : Method 'SetSize' hides virtual method of base type 'TStream' 祖父類別的相關資料如下 TStream = class(TObject) procedure SetSize(NewSize: Longint); overload; virtual; 問題二、儘管目前以 procedure SetSize(NewSize: longint); override; 方式卻還是在property這行 property Size: int64 read GetSize write SetSize; 出現錯誤訊息[Error] : Incompatible types 我的程式如下:
function TMPHMemoryStream.GetSize: int64;
var
  nPos: int64;
  nSize: ULARGE_INTEGER;
begin
  if FStyle = False then
    begin
      nPos := Seek(0, soCurrent);
      Result := Seek(0, soEnd);
      Seek(nPos, soBeginning);
    end
  else
    begin
      nSize.QuadPart := 0;
      nSize.LowPart := GetFileSize(FHandle, @nSize.HighPart);
      Result := nSize.QuadPart;
    end;
end;
procedure TMPHMemoryStream.SetSize(NewSize: longint);
begin
  FSize := NewSize;
end;
ccchen
版主


發表:61
回覆:940
積分:1394
註冊:2002-04-15

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-03-04 08:11:04 IP:61.219.xxx.xxx 未訂閱
依TStream之原始宣告來看
  TStream = class(TObject)
  private
    function GetSize: Int64;
    procedure SetSize64(const NewSize: Int64);
  protected
    procedure SetSize(NewSize: Longint); overload; virtual;
    procedure SetSize(const NewSize: Int64); overload; virtual;
  public
    property Size: Int64 read GetSize write SetSize64;
  end;
1. SetSize有兩個型態, 不能做為property 之write method(你的程式找到第一型態故Incompatible types),所以原始碼是用SetSize64, 在setSize64中以傳入參數之型態來決定呼叫那一個. (因此如果你只要改setsize則不需改property 宣告, 直接override SetSize即可) 2. 你需要改GetSize, 而GetSize為private無法override, 故選擇直接取代, 此時必須重宣告
    property Size: Int64 read GetSize write SetSize64;
然而此宣告破壞了原SetSize之機製, 所以只好連SetSize64一起重寫
TMPHMemoryStream = class(TMemoryStream)
  procedure SetSize64(const NewSize: Int64); 
  function GetSize: int64;
  procedure SetSize(NewSize: longint); override;
  property Size: int64 read GetSize write SetSize64;
end;    procedure TMPHMemoryStream.SetSize64(const NewSize: Int64);
begin
  SetSize(NewSize);
end;
如此應該就沒問題了
BGman
初階會員


發表:28
回覆:85
積分:42
註冊:2003-01-10

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-03-04 10:34:16 IP:211.22.xxx.xxx 未訂閱
感謝ccchen兄的指點,小弟還是有點不懂 我的目的是將TMemoryStream Load 的機制,改成 Handle 的方式, 而非實體載入,如此開啟數 Giga 檔案時才不會佔用大量資源並浪費載入時間。 所以我必須 Asign Stream 的 Size ,Grid 才知道顯示的邊界有多大。    在程式執行時,下了中斷點,可以利用Debug Inspector 來觀察變數 在Debug Inspector 所顯示的資訊,分為三區 第一區:Data ,記錄著Private 區的變數 第二區:Method 第三區:Property ,記錄著自己的property 與繼承來的property,例如 Size/ TStream.GetSize/TStream.SetSize64 未改寫前 Size/TMPHMemoryStream.GetSize/TMPHMemoryStream.SetSize64 改寫後 我的疑問是 第一:Delphi 是不是都要藉由 property ,將子類別的資料傳給父類別 例如,TStream 有一個private 變數 FSize ,記錄著Stream 的大小 在C 的做法是在宣告函式的地方指定 TMPHMemoryStream::SizeSize64(int64 NewSize):TStream(FSize){}; 第二:如果我在TMPHMemoryStream 類別,也宣告一個Private 的FSize 是否有取代的作用?
ccchen
版主


發表:61
回覆:940
積分:1394
註冊:2002-04-15

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-03-04 11:27:29 IP:61.219.xxx.xxx 未訂閱
第二:如果我在TMPHMemoryStream 類別,也宣告一個Private 的FSize 是否有取代的作用? 那是完全取代了, 由於是private, 子class無法存取Ancester Class之值, 故須注意AnCester Class中若有其他method存取此Fsize之值, 也同樣改不到子class之值, 變成兩個完全不一樣的參數. 故如此做很不理想. Delphi 是不是都要藉由 property ,將子類別的資料傳給父類別 那也不一定, 只要不是private, 變數, procedure, function在子類別與父類別間均可一樣存取 TStream中並無fsize之宣告, fSize是宣告在TCustomMemoryStream中 其實我覺得既然要改load機制, 應該由TStream繼承起反而容易些 資料由何處載入, file嗎? 為何不用FileStream?
BGman
初階會員


發表:28
回覆:85
積分:42
註冊:2003-01-10

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-03-04 11:29:14 IP:211.22.xxx.xxx 未訂閱
關於問題二,我之所以這樣問,是因為:當我執行完 FDataStorage.Size := GetFileSize(FDataStorage.Handle, nil); 用 Debug Inspector 觀察[property區]Size 還是0 如果我在 Private 加入 FSize 在Debug Inspector 觀察[data區] FSize 可以得到非0的值 但是我不確定,在Delphi中,自己加的FSize 是否有取代祖父類別FSize 的作用
BGman
初階會員


發表:28
回覆:85
積分:42
註冊:2003-01-10

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-03-04 12:07:53 IP:211.22.xxx.xxx 未訂閱
1.為何要繼承自TMemoryStream ,是因為我所改寫的元件裡,他還有一個 Undo 的機制是繼承TMPHMemoryStream,所以在我對Delphi了解不夠的情況下 我不敢輕舉妄動! 不過,在ccchen 兄 Support 之下,我漸漸了解Delphi 了 2.請問一下ccchen 兄,據你所知,TFileStream 是不是直接把整個檔案 Load 進記憶體,THandleStream 是不是比較適合我這個例子? 可以給我點意見嗎? 感激不盡!
ccchen
版主


發表:61
回覆:940
積分:1394
註冊:2002-04-15

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-03-04 13:14:22 IP:61.219.xxx.xxx 未訂閱
TFileStream 也是繼承至THandleStream, 只是多了FileMode的管理 TFileStream 並不會直接把整個檔案Load 進記憶體
系統時間:2024-05-04 14:19:00
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!