CPP雜記——移動構造函數中需要注意的問題

首先提一下爲什麼要使用移動構造函數:
在多次使用傳值做參數的方法時,不可避免的會產生臨時對象從而調用拷貝構造函數。
.
默認的淺拷貝構造函數在臨時變量被析構時還會釋放其中的動態元素內存,這時便會對其他部分產生影響,c++11前未仔細優化的代碼大都直接編寫深拷貝構造函數,但由於作爲參數的臨時性,這種行爲是無必要的。
.
這時的優化方法爲使用“右值引用”,通過直接取得傳入臨時變量的所有權,可令如push_back(tempClass(args…))此類的函數只調用一次構造函數
具體做法:實現參數類型爲const T& 或者 T&& 類型的具體方法

1.在移動構造函數中結束對原臨時變量的引用時,需要將右值引用設置爲nullptr釋放原有的臨時變量資源,eg:
MyObject& operator=(MyObject&& obj /*const MyObject& obj*/) noexcept {
       delete 		m_pData;
       m_pData 		= obj.m_pData;
       obj.m_pData 	= nullptr; 		//釋放臨時資源 shared_ptr
       return *this;
}
2.注意,不能習慣性的在右值引用前加上const,否則仍會導致二次拷貝的調用

…關於const 右值引用的用途,我猜可能是防止編譯上的一些問題?比如不讓const左值調用右值版本的函數,,?我還是暫且矇在鼓裏

3.最後,1中實現的版本還有着一個重大的問題,即在自身作爲參數時會導致源值在函數結束後被釋放,eg:
MyObject o(364364);
MyObject b = std::move(o);
cout << (uintptr)o.m_pData << endl;

輸出結果爲: 0
顯然,o中的成員被清除了,這都是由於

obj.m_pData 	= nullptr; 		

爲了避免這種情況需要添加代碼爲如下形式:

MyObject& operator=(MyObject&& obj /*const MyObject& obj*/) noexcept {
	   //Coco
	   if(&obj == this) return *this;
	   
       delete 		m_pData;
       m_pData 		= obj.m_pData;
       obj.m_pData 	= nullptr;
       return *this;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章