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

TStringList 用法

答題得分者是:aftcast
deanmac85
一般會員


發表:13
回覆:4
積分:3
註冊:2007-05-29

發送簡訊給我
#1 引用回覆 回覆 發表時間:2010-11-01 19:18:44 IP:210.68.xxx.xxx 未訂閱
請問TStringList 宣告方式及free方式寫法
哪一個正確
爬文後有許多版本
雖然compiler都ok~但是差別在哪裡
怎麼寫才正確

宣告1 : TStringList *pStream = new TStringList ;
宣告2 : TStringList *pStream = new TStringList() ;

.......

Free1 : delete pStream ;
Free2 : pStream->Free() ;


aftcast
站務副站長


發表:81
回覆:1482
積分:1762
註冊:2002-11-21

發送簡訊給我
#2 引用回覆 回覆 發表時間:2010-11-01 20:48:53 IP:220.135.xxx.xxx 訂閱

宣告1 : TStringList *pStream = new TStringList ;
宣告2 : TStringList *pStream = new TStringList() ;

二個寫法都是一樣的結果。只是我個人建議用宣告2比較不會讓人混亂。 第一種的寫法就是使用 預設建構式 來建物件。 而 ( ) 裡空的,也表呼叫預設建構式。


Free1 : delete pStream ;
Free2 : pStream->Free() ;

上面二個就有點不一樣。建議使用 delete。 第二種方式似乎是"拿delphi的觀念來處理c "。
c 的 delete 就會呼叫 解構,解構應該會做一些事(或沒有),然後再呼叫 free( ) 這個方法。
所以 delete 才是標準的!


------



蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
Coffee
版主


發表:31
回覆:878
積分:561
註冊:2006-11-15

發送簡訊給我
#3 引用回覆 回覆 發表時間:2010-11-02 14:06:44 IP:220.130.xxx.xxx 訂閱
第二點我有點好奇BCB裡面是否有對delete去作一些特殊的處理,也順便補充一下Delphi的作法。
Delphi實際上的destructor是destroy();,也就是實際上在自動回收的時候會呼叫的是destructor destroy,而不是Free。
Free的作用,根據我的理解是當我們必須要顯式的調用解構子時所下的一層保護,它會去檢查該指標是否存在,再決定是否要執行destructor。
也因此,我們其實直接呼叫myObj.destroy();來釋放,也可以呼叫myObj.Free();。
呼叫destroy的時候,我們通常會這麼寫:
if(myObj) delete myObj;或者是Delphi style的if(myObj) myObj->destroy();
而呼叫時,我們交給free去檢查,因此只要:
myObj.Free();
Free裡面通常只會有if(this) this.destroy();//不好意思,不記得實際的code,但大致上的意思是如此。
在C 裡面直接呼叫delete會直接呼叫解構子 destroy(),因此如果你的程式習慣良好,其實Free()跟destroy()其實是一樣的。
在C 中,被delete後的指標仍然會指向已釋放的位址,在Delphi中也是如此,因此Delphi為了讓程式碼更簡潔,在Delphi 6之後提供了FreeAndNil(myObj)的方式來進行釋放並將指標歸0。







===================引 用 aftcast 文 章===================

宣告1 : TStringList *pStream = new TStringList ;
宣告2 : TStringList *pStream = new TStringList() ;

二個寫法都是一樣的結果。只是我個人建議用宣告2比較不會讓人混亂。 第一種的寫法就是使用 預設建構式 來建物件。 而 ( ) 裡空的,也表呼叫預設建構式。


Free1 : delete pStream ;
Free2 : pStream->Free() ;

上面二個就有點不一樣。建議使用 delete。 第二種方式似乎是"拿delphi的觀念來處理c "。
c 的 delete 就會呼叫 解構,解構應該會做一些事(或沒有),然後再呼叫 free( ) 這個方法。
所以 delete 才是標準的!


------
不論是否我發的文,在能力範圍皆很樂意為大家回答問題。
為了補我的能力不足之處,以及讓答案可以被重複的使用,希望大家能儘量以公開的方式問問題。
在引述到我的文時自然會儘量替各位想辦法,謝謝大家!
GrandRURU
站務副站長


發表:234
回覆:1651
積分:1742
註冊:2005-06-21

發送簡訊給我
#4 引用回覆 回覆 發表時間:2010-11-02 14:16:44 IP:203.75.xxx.xxx 未訂閱
C++的話我會比較推auto_ptr來處理
來規避「被delete後的指標仍然會指向已釋放的位址」的問題

然而,delete後再指向null也是一個好方法

不過前提是使用TRY FINALLY

===================引 用 Coffee 文 章===================
第二點我有點好奇BCB裡面是否有對delete去作一些特殊的處理,也順便補充一下Delphi的作法。
Delphi實際上的destructor是destroy();,也就是實際上在自動回收的時候會呼叫的是destructor destroy,而不是Free。
Free的作用,根據我的理解是當我們必須要顯式的調用解構子時所下的一層保護,它會去檢查該指標是否存在,再決定是否要執行destructor。
也因此,我們其實直接呼叫myObj.destroy();來釋放,也可以呼叫myObj.Free();。
呼叫destroy的時候,我們通常會這麼寫:
if(myObj) delete myObj;或者是Delphi style的if(myObj) myObj->destroy();
而呼叫時,我們交給free去檢查,因此只要:
myObj.Free();
Free裡面通常只會有if(this) this.destroy();//不好意思,不記得實際的code,但大致上的意思是如此。
在C 裡面直接呼叫delete會直接呼叫解構子 destroy(),因此如果你的程式習慣良好,其實Free()跟destroy()其實是一樣的。
在C 中,被delete後的指標仍然會指向已釋放的位址,在Delphi中也是如此,因此Delphi為了讓程式碼更簡潔,在Delphi 6之後提供了FreeAndNil(myObj)的方式來進行釋放並將指標歸0。







===================引 用 aftcast 文 章===================

宣告1 : TStringList *pStream = new TStringList ;
宣告2 : TStringList *pStream = new TStringList() ;

二個寫法都是一樣的結果。只是我個人建議用宣告2比較不會讓人混亂。 第一種的寫法就是使用 預設建構式 來建物件。 而 ( ) 裡空的,也表呼叫預設建構式。


Free1 : delete pStream ;
Free2 : pStream->Free() ;

上面二個就有點不一樣。建議使用 delete。 第二種方式似乎是"拿delphi的觀念來處理c "。
c 的 delete 就會呼叫 解構,解構應該會做一些事(或沒有),然後再呼叫 free( ) 這個方法。
所以 delete 才是標準的!


aftcast
站務副站長


發表:81
回覆:1482
積分:1762
註冊:2002-11-21

發送簡訊給我
#5 引用回覆 回覆 發表時間:2010-11-02 14:38:14 IP:210.64.xxx.xxx 訂閱
coffee兄的補充讓我提起了好奇心 ^_^

上面我寫道:「c 的 delete 就會呼叫 解構,解構應該會做一些事(或沒有),然後再呼叫 free( ) 這個方法。」 這是我半猜測的。然而,我剛認真的去查了一下help檔,它寫著:

TObject::Free

Destroys an object and frees its associated memory, if necessary.

__fastcall Free();

Description

Do not call the Free method of an object. Instead, use the delete keyword, which invokes Free to destroy an object. Free automatically calls the destructor if the object reference is not NULL.

看起來就像是我猜的一樣。 但我的說法 : 「解構應該做一些事(或沒有)」,這就是我沒認真的去查原碼的說法。到底有沒有額外的處理? 我還是沒查…但說明上有點透出詭異---- delete 若單純只叫 free,那為何 建議不要 直接呼叫 free 而使用delete ?

至於delphi…好了,我近年來不很熟它(忘了),可能像 coffee兄說的。delphi的物件導向就我所知和一般的c /java不完全一樣。比如建購時 子再父,而非一般的父再子 (我印象若沒錯話)… 可能還有一些點點點的… 所以,coffee 兄說的關於delphi的用法,我想應該很正確。



------



蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
編輯記錄
aftcast 重新編輯於 2010-11-02 00:38:54, 註解 無‧
Coffee
版主


發表:31
回覆:878
積分:561
註冊:2006-11-15

發送簡訊給我
#6 引用回覆 回覆 發表時間:2010-11-02 14:53:10 IP:220.130.xxx.xxx 訂閱
被發現不熟BCB了..:P
前面我用的C 是在GNU跟MFC上,所以印象中delete是會直接進行釋放的,看來BCB也跟Delphi一樣,在顯式呼叫解構的時候一樣會繞到Free這個method進行檢查,然後才真正的呼叫解構子?

至於Delphi根據我的理解應該也是先父再子,解構時先子再父,因此textbook都會建議使用以下的型式來進行建/解構:


[code delphi]
constructor Create;
begin
inherited;//先呼叫父代建構子進行建構
doMyClassConstruction();//進行本類別的建構;
end;

destructor Destroy;
begin
doMyClassDestruction();//先解構本類別所自行產生的記憶體
inherited;//再呼叫父代解構子進行解構
end;

procedure Free;//至於Free不建議更動或放置任何要釋放的記憶體,應交由destructor執行。因為Free僅檢查記憶體是否assigned;
begin
inherited;
end;
[/code]

至於help上建議使用delete而不要使用Free,我個人認為是為了coding style的問題,如同上述的Free不建議更動一樣,除了維持程式碼可讀性,也使得將來在修改framework時減少難以預期的程式碼結構問題。因此Delphi我記得也是建議不要直接呼叫destructor,而是直接呼叫Free。


===================引 用 aftcast 文 章===================
coffee兄的補充讓我提起了好奇心 ^_^

上面我寫道:「c 的 delete 就會呼叫 解構,解構應該會做一些事(或沒有),然後再呼叫 free( ) 這個方法。」 這是我半猜測的。然而,我剛認真的去查了一下help檔,它寫著:

TObject::Free

Destroys an object and frees its associated memory, if necessary.

__fastcall Free();

Description

Do not call the Free method of an object. Instead, use the delete keyword, which invokes Free to destroy an object. Free automatically calls the destructor if the object reference is not NULL.

看起來就像是我猜的一樣。 但我的說法 : 「解構應該做一些事(或沒有)」,這就是我沒認真的去查原碼的說法。到底有沒有額外的處理? 我還是沒查…但說明上有點透出詭異---- delete 若單純只叫 free,那為何 建議不要 直接呼叫 free 而使用delete ?

至於delphi…好了,我近年來不很熟它(忘了),可能像 coffee兄說的。delphi的物件導向就我所知和一般的c /java不完全一樣。比如建購時 子再父,而非一般的父再子 (我印象若沒錯話)… 可能還有一些點點點的… 所以,coffee 兄說的關於delphi的用法,我想應該很正確。



------
不論是否我發的文,在能力範圍皆很樂意為大家回答問題。
為了補我的能力不足之處,以及讓答案可以被重複的使用,希望大家能儘量以公開的方式問問題。
在引述到我的文時自然會儘量替各位想辦法,謝謝大家!
aftcast
站務副站長


發表:81
回覆:1482
積分:1762
註冊:2002-11-21

發送簡訊給我
#7 引用回覆 回覆 發表時間:2010-11-02 17:14:25 IP:210.64.xxx.xxx 訂閱
coffee 兄…  這變成我們二人的研討區了啦 > <

inherited;//先呼叫父代建構子進行建構 ,其實delphi就是靠這行來 「先父再子」,但若你不自己加這行,那就是先子在父了…

若你有裝 bcb 6,在其help檔裡,內容->Programming with c builder -> c language support for the vcl and clx 的章節--> object construction for c buildervcl/clx classes

這裡面的內容有題到,如何混 delphi 的類別與c 的類別。其中圖也畫的很清楚… (這部份少人去讀,我也是讀了這裡後才發現delphi竟不一樣@@)

我不知自己是否還有什麼沒注意到的…@@


------



蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
編輯記錄
aftcast 重新編輯於 2010-11-02 03:19:36, 註解 無‧
系統時間:2017-10-21 11:07:47
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!