如何改寫TMemoryStream的Size Property? |
尚未結案
|
BGman
初階會員 發表:28 回覆:85 積分:42 註冊:2003-01-10 發送簡訊給我 |
我要改寫繼承自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 發送簡訊給我 |
依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 發送簡訊給我 |
感謝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 發送簡訊給我 |
第二:如果我在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 發送簡訊給我 |
|
BGman
初階會員 發表:28 回覆:85 積分:42 註冊:2003-01-10 發送簡訊給我 |
|
ccchen
版主 發表:61 回覆:940 積分:1394 註冊:2002-04-15 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |