移動構造函數


所用的C++特性:右值引用

所用到的技術:移動語義

何謂移動語義:前提(所提及的指針是類內指針,且指向類內的動態內存分配操作的內存空間)

  基於內存的思想,對於堆內存,總是會涉及到申請和釋放;而有些時候我們並不需要當前的內存資源所存的數據立即被釋放掉(此處延伸一下,對所謂的釋放,我理解的是:堆內存空間被申請用來存放一定的數據,這塊位置用完之后就要還給系統,即在堆內存的管理鏈表中重新被認定為空閑內存,里面的數據是否需要被清洗掉,此處不詳,總之這塊位置被歸到空閑表中了),就是說,我這塊空間暫時不想你被收回去(對於堆內存,只要你不主動釋放,且始終有正確的指針指向它,系統會認為它一直是有效的非空閑的,因此才會引起“內存泄漏”,即老賴,“用了不還那種”),但是系統出於保護,往往會在限定的條件下自動調用析構函數,強制幫你釋放掉當前指針所申請的這塊內存,而在我們顯示析構時,往往是在~A()中delete這個指針,即系統是根據這個指針(地址)以及它自身的類型(有類型才知道該收回多大空間啊,分配時同理)去完成回收工作的,因此,此時的移動構造技術實際上就是從這里切入的(因此我們需要從原理上去理解這個技術為什么而存在以及其合理性):我將當前對象的指針申請的這塊空間綁定到另一個類對象的指針不就行了啊,而原指針也必然會被其所在的析構函數釋放掉對應的資源,因此將其置為nullptr就太特么合理了!而新指針屬於對象,也必然將被析構函數釋放掉對應的內存。這招“偷天換日”就是移動構造的關鍵。

  此處所舉例的應用背景是:返回一個局部變量(自定義類型),對於臨時對象的資源使用移動構造函數代替復制構造函數完成其對應的功能,可以減少一次深拷貝操作(這對於大容量的堆內存復制是非常有效的)。

 

 

 

 解釋:

  上圖中,getNum()函數中需要返回的是一個局部變量,因此它此時就是一個臨時變量,因為在函數結束后它就消亡了,對應的其動態內存也會被析構掉,所以系統在執行return函數之前,需要再生成一個臨時對象將a中的數據內容返回到被調的主函數中,此處自然就有兩種解決方法:1、調用復制構造函數進行備份;2、使用移動構造技術把即將消亡的且仍需要用到的這部分內存的所有權進行轉移,手動延長它的生命周期。

顯然,前者需要深拷貝操作依次復制全部數據,而后者只需要“變更所有權”即可。

此處更需要說明的是:遇到這種需求時,編譯器會很智能幫你選擇類內合適的構造函數去執行,如果沒有移動構造函數,它只能默認的選擇復制構造函數,而同時存在是自然會優先選擇移動構造函數。

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM