怎樣理解C 中「如果屬性有在堆區開闢的,一定要自己提供拷貝建構函式,防止淺拷貝帶來的問題」?

時間 2021-10-22 19:04:26

1樓:CuKing

對但不完全對。

對是因為,比如實現乙個字串類,裡面有乙個指標指向字串所在地,析構是delete這個指標,那麼拷貝直接拷這個指標,之後會析構兩次就delete兩次就掛了。

不對是因為,比如我可能雖然存了乙個指標,但是另有地方統一管理這個資源,那當然也沒必要提供。

其實這種一刀切的話基本沒幾句是對的,哪怕是new必須delete,也不完全對,有的時候要實現乙個某種型別的記憶體池,可能就是只new不delete,留著復用,程式退出時留給系統擦屁股。

2樓:NaN

這話不僅是廢話,還是沒說清楚的廢話。

你什麼時候需要提供拷貝建構函式?在預設的拷貝建構函式的行為不正確的時候。什麼時候預設的拷貝建構函式行為不正確?乙個可能,在你有額外資料需要複製的時候。

那麼在什麼情況下你有額外的資料需要複製?這是乙個很具體但並不難回答的問題,對吧。

如果確實有額外資料,但不需要複製,那麼。。。那麼你需要智慧型指標,引用計數或者cow。那麼這時你是否需要自己提供拷貝建構函式,那就要看具體實現了:這其實是所有權問題。

3樓:扶餘城裡小老二

有乙個筐在高位,和一堆蘋果分別在2個地方。每個蘋果都有根線連著筐。需要對應蘋果得時候,一拽線,蘋果就過來了。用完一鬆手,蘋果又回到了原地。

那麼淺拷貝就是複製了乙個筐和線。深拷貝就是連帶蘋果也複製了。

淺拷貝的結果就是多個筐共享同一堆蘋果。

正常的話就是乙個筐的工廠和乙個蘋果工廠。

使用者先從筐工廠申請乙個筐,然後,又跟蘋果工廠申請了一堆蘋果,然後,用筐與蘋果連線,二者隸屬於不同位址塊。

4樓:

瀉藥!拷貝建構函式的乙個作用就是定義淺拷貝的行為。

如果乙個例項的成員是new出來的,直接將這個成員共享給淺拷貝的新例項,淺拷貝的呼叫者需要十分小心使用新例項,防止double free且小心處理共享的資料互相影響。

如果提供拷貝建構函式可以根據需要定義這個共享的資料的行為。

5樓:新生命

老生常談了,其實無論類物件是在什麼區域開闢的,都要寫好拷貝構造和析構。在可能的情況下最好用= default = delete以減少隱含錯誤和提公升效能。類當中用智慧型指標就可以妥善這個問題。

我曾經出過一道面試題,說乙個含有指標的類如何寫符合語義右值的賦值函式,答對者寥寥無幾。A&

A::operator=(

A&&r)

noexcept

return

*this;}

但如果使用了智慧型指標。

直接A& A::operator=(A&& r)noexcept = default;即可。

6樓:秦雨貓

這句話是不準確的。std::vector最常見的實現也是在堆區分配,但直接作為類成員、且值型別為物件的std::vector是自動實現深拷貝的。

準確的說法是:「當類存在由開發者手動管理的物件,或由智慧型指標管理的物件時,預設複製構造將進行淺拷貝。開發者應當根據設計意圖,實現深拷貝或淺拷貝的複製建構函式」。

7樓:pansz

這就是,字面意思理解就行吧。

所以,你是不理解屬性,還是不理解堆區開闢,還是不理解拷貝構造,還是不理解淺拷貝?

我給題主乙個思路,去學習下淺拷貝的含義,估計應該問題就解決了。

8樓:

這個問題非常好!

首先你應該知道堆記憶體的特點(1)

動態記憶體和指標變數

其次你應該知道C++物件賦值/複製的預設行為(2)物件之間賦值

拷貝建構函式

第三,上面兩點結合起來,當類有成員是指標的時候,類在拷貝物件的時候拷貝的是指標的值,而沒有重新開闢一塊記憶體去指向。(3)

複製控制 copy control(非平凡的類)第四,這時候你要知道動態記憶體是由建構函式和析構函式來管理的(4)複製控制 copy control(非平凡的類)第五,兩個物件的析構函式會析構同一塊記憶體,程式崩潰!(5)複製控制 copy control(非平凡的類)

9樓:九零後老漢

指標預設淺拷貝,只複製位址,如果類有指標指向堆,那麼物件在複製的時候就會出現多個指標指向同一記憶體。重複釋放,野指標,執行緒不安全,記憶體洩漏等問題

10樓:

堆區就是new的物件。簡單來說就是防止指標拷貝。

預設拷貝僅指標拷貝,結果就是兩個物件的成員指向同一塊記憶體。可能引起的問題主要有兩個:

一邊釋放後,另一邊指標變野

兩邊重複釋放記憶體

兩種結果都不可預料

Java中的類和c 中的類,在使用中要理解?

Lieu 長文慎入,內含 星際 穿越 我覺得這是乙個程式語言設計的問題,也是個空間緯度的問題.很有意思.還沒接受過科班的CS的訓練,程式設計經驗僅限J2EE的前後端,拋磚引玉,談談自己的思考.二維世界 我認為程式語言的基本元素是操作符和變數,而通過操作符操作變數這一行為即乙個語句.比如有變數a,有操...

怎樣理解王菲的《郵差》中「你是千堆雪我是長街,怕日出一到彼此瓦解這句歌詞的意思?

Ani kinnor 日出一到,雪就化了,瓦解掉了,這好理解。但長街呢?為什麼也跟著瓦解?因為這樣一來,積雪覆蓋下的長街就不會是一條平整氣派的大道,而會是一條斑駁而滄桑的道路,一條你可以想見的長起青苔的古道。所以日出雪化後,你看到的是一條 瓦解了 的長街。雪覆蓋在上面的時候,你看到的是一條美麗雪白的...

在C 中 String Empty和 有什麼區別?

Ken.W 這類問題去stackoverflow問效果更好 榮浩 String.Empty是String類裡已經例項化好的靜態唯讀空字串,我們可以直接拿來用。而對於 系統需要去託管堆上例項化乙個空字串,效能略差一些吧 這種說法是錯誤的!Strings1 String Empty Strings2 C...