[問題] class destructor

作者: s5031588 (好馬兒)   2017-10-08 20:45:23
▉▂開發平台(Platform): (Ex: Win10, Linux, ...)
MacOSX
編譯器(Ex: GCC, clang, VC++...)+目標環境(跟開發平台不同的話需列出)
g++5.4
問題(Question):
大家好,最近在修資料結構這門課,過去雖然有修過計算機程式
,但是兩學分的課所以感覺學得不是很扎實,對於class的部分只有粗略帶過..
所以來這邊請教大家:
對於一個data member中含有pointer的class,初始時會用new配置記憶體,
而自行建立的destructor會用delete釋放配置給該指標的記憶體,請問這樣的狀況下
該怎麼在member function中回傳一個local的class變數呢?
因為函數功能的需要,必須在函數中宣告一個class變數a來承接運算的結果,並return
該變數給calling function,由calling function中的class變數b承接,但是這樣的情
況下,由於member function terminates, destructor將a裡面的pointer給delete掉,
造成calling function中b裡面的指標指向一個直隨時有可能被修改的地方...
有自己試著去overload operator=及建立copy constructor來看看是否可以讓calling
function 中b裡面的pointer指向一個新的地方,在複製a的值過去,但好像a會先被
destructed(?!)..
上網查了很多destructor, return object的關鍵字,都找不到想要的答案..
在這裡麻煩大家解答了..
在下面附上class 的程式碼,大致上是我在建立一個stack的class 有一個destructor:
~Stack(){delete [] stack
初始的constructor有用new給該指標動態配置記憶體
問題卡在是我要寫一個member function splitStack(),作用是要將某個stack從中間
某個點分開拆成兩個stack,所以這個function 必須return stack型態的variable,
但是splitStack()中宣告的first再回傳值給main後,就被解構了..
程式碼(Code):(請善用置底文網頁, 記得排版)
http://codepad.org/IjGU1cDW
作者: jerryh001   2017-10-08 21:07:00
是要定義copy constructor沒錯 看看有沒有哪裡寫錯發現個奇怪的地方 destructor不應該手動呼叫
作者: s5031588 (好馬兒)   2017-10-08 22:07:00
請問j大 copy constructor該怎麼寫呢?因為我造我的邏輯寫還是沒辦法欸..附上我copy constructor的程式碼:http://codepad.org/hP4cyP6b順便附上main的程式碼http://codepad.org/TcOdcyCc我用一步步執行發現,雖然copy function不會讓兩個POINTER 直接相等,但是splitStack一結束,居然會兩個指標都destruct...= =,有人可以解釋原理嗎QQ
作者: jerryh001   2017-10-08 22:40:00
operator=也要留吧copy ctor 的參數也許也要<T>嗎? 有點忘了
作者: stucode   2017-10-08 23:20:00
怎麼寫完 copy ctor 後 operator = 就不見了XD?1. copy constructor 裡面不用 delete,因為是初始化,還沒有前值,直接 new 然後 copy 就好。2. copy assignment 需要檢查並釋放(或重新利用)現有資源,同時要避免 self-assignment 造成錯誤的delete。3. copy assignment 請傳回 reference,不要傳值。4. splitStack() return first 就好,不用再包一層。其實你的指標幾乎都是在 3. 或 4. 多餘的臨時物件中被delete 掉的。不過如果有做好 deep copy,頂多就是多跑幾次 copy 效能較差而已,也不至於會使用到被 delete掉的指標,造成嚴重錯誤。
作者: lc85301 (pomelocandy)   2017-10-09 01:04:00
傳回reference 是要允許使用 move 來減少一次 copy 吧
作者: stucode   2017-10-09 05:57:00
傳回值的話,比較容易產生不必要的臨時物件。除此之外,還可能導致非使用者預期的行為。其實 C++ 並沒有硬性規定 copy assignment 要傳回 reference。這比較像是一種慣例,讓自定義類別的行為盡可能相似於 C++ 原生型別(如 int)的行為。減少類別使用時產生意料之外的效果。另外一個理由是,CopyAssignment requirements 要求回傳型態必須是 T&,沒有滿足這個條件可能無法正常使用某些標準容器的方法。事實上,如果沒有為類別宣告這個函數,編譯器自動幫你生成的版本也是傳回 reference。當然,如果你有更好的理由傳回新物件或者是其他型別,那就不用客氣的傳吧!只要確保使用者了解並正確使用你的類別即可。
作者: james732 (好人超)   2017-10-09 10:02:00
順便學一下什麼是rvalue reference與move吧XD
作者: Caesar08 (Caesar)   2017-10-09 13:50:00
如果你想要預先allocate一些memory來用,你需要知道placement new才行。今天destructor沒問題是因為T是int建議先看gcc或msvc的vector怎麼實作vector,再實作stack
作者: stucode   2017-10-09 20:09:00
實測了一下,解構都正常喔。如果你有開最佳化(或者是IDE 的 Release mode),那 first 可能被 RVO 掉,實際解構會在 b 生命週期結束時(離開 main() 時)發生。另外,複製建構函數裡的 new 括號錯了。

Links booklink

Contact Us: admin [ a t ] ucptt.com