目錄
因為不熟悉析構函式的生成機制,導致了乙個bug。
首先,下面的**沒有問題,因為資料成員m_,所以widget預設也是個只移型別;mm中也可以插入乙個由只移型別構造的std::pair,因為pair預設支援右值引數構造(可以由只移的widget構造)和自身的移動建構函式(可以移動構造到unordered_map中):
class widget ;
unordered_map mm;
mm.insert();
然後,我手賤加了乙個預設的析構函式:
class widget ;
unordered_map mm;
mm.insert(); // error!
報錯資訊極長,核心錯誤是:
error: no matching function for call bjlkpto 『std::unordered_map>::insert(
)' 45 | unord程式設計客棧ered_map mm;
可以把std::pair的構造單獨抽出來看到更清晰的報錯資訊:
// **如下:
make_pair(12, widget());
// 報錯如下:
in template: no matching constructor for initialization of '__pair_type' (aka 'pair')
「顯然」,是因為widget的移動建構函式被隱式刪除了(它既不能拷貝也不能移動了),所以無法由widget引數構造乙個std::pair。
解決方案就是不要定義析構函式,或者顯式定義乙個移動建構函式:
class widget ;
unordered_map mm;
mm.insert();
在我做試驗的時候,一開始錯把std::mutex記成了只移型別
定義了乙個這樣的類:
class widget ;
unordered_map mm;
mm.insert(); // error!
甚至在我沒有新增析構函式的時候widget就不能拷貝和移動了。
看看原始碼:
class mutex : private __mutex_base
顯然,因為mutex自行定義了預設的析構函式而且把拷貝建構函式定義為刪除的,那麼它的移動建構函式也會被隱式刪除,所以mutex既不能拷貝也不能移動。
和std::thread原始碼比較一下:
class thread
~thread()
}雖然std::thread定義了析構函式和刪除的拷貝建構函式,但是它顯式定義了移動建構函式,這使得它雖然不能拷貝但是可以移動。
大體來說就是std::mutex一般由多個執行緒呼叫,那麼如果它的位置可以變化,那麼怎麼讓所有執行緒都知道它的新位置在**呢?
詳見stackoverflow:
本文標題: c++類的特種函式生成機制詳解
本文位址:
c 類的建構函式詳解
c 類的建構函式詳解 一 建構函式是幹什麼的 class counter private 資料成員 int m value 該類物件被建立時,編譯系統物件分配記憶體空間,並自動呼叫該建構函式 由建構函式完成成員的初始化工作 eg counter c1 編譯系統為物件c1的每個資料成員 m value...
c 類的建構函式詳解
c 建構函式的知識在各種c 教材上已有介紹,不過初學者往往不太注意觀察和總結其中各種建構函式的特點和用法,故在此我根據自己的c 程式設計經驗總結了一下c 中各種建構函式的特點,並附上例子,希望對初學者有所幫助。c 類的建構函式詳解 一 建構函式是幹什麼的 class counter private ...
c 類的建構函式詳解
c 建構函式的知識在各種c 教材上已有介紹,不過初學者往往不太注意觀察和總結其中各種建構函式的特點和用法,故在此我根據自己的c 程式設計經驗總結了一下c 中各種建構函式的特點,並附上例子,希望對初學者有所幫助。c 類的建構函式詳解 一 建構函式是幹什麼的 class counter private ...