在c++中,乙個類有八個預設函式:
預設建構函式;
預設拷貝建構函式;
預設析構函式;
預設過載賦值運算子函式;
預設過載取址運算子函式;
預設過載取址運算子const函式;
預設移動建構函式(c++11);
預設過載移動賦值操作符函式(c++11)。
classc++ 預設建構函式是對類中的引數提供預設值的建構函式。如果使用者沒有定義建構函式,那麼編譯器會給類提供乙個預設的建構函式,但是只要使用者自定義了任意乙個建構函式,那麼編譯器就不會提供預設的建構函式。myclass
;
在c++11中可通過=default顯式指定採用預設建構函式。
當類中沒有定義拷貝建構函式時,編譯器會預設提供乙個拷貝建構函式,進行成員變數之間的拷貝。
具體來說,編譯器會直接使用"="進行值拷貝。一般型別中,"="的行為是值拷貝,而成員中有指標型別時,則會指複製指標,不複製指標指向的內容,產生淺拷貝。
進一步,當類中某些成員的賦值運算子函式"="被delete掉(如unique_ptr,std::atomic等,或其他自定義型別),無法呼叫時,編譯器將無法提供預設拷貝建構函式。例子見後文。
如果使用者沒有定義建構函式,編譯器將為我們建立乙個預設析構函式。
當程式沒有顯式地提供乙個以本類或本類的引用為引數的賦值運算子過載函式時,編譯器會自動生成這樣乙個賦值運算子過載函式。
預設過載賦值運算子函式與預設拷貝建構函式的行為類似,編譯器會直接使用"="進行值拷貝,當類中某些成員的賦值運算子函式"="被delete掉時,編譯器將無法提供預設的過載賦值運算子函式
如果沒有顯式定義,編譯器會自動生成預設的過載取址運算子函式,函式內部直接return this,一般使用預設即可。
與過載取址運算子函式類似,取位址後返回const型別
滿足以下條件時,編譯器將生成預設的移動建構函式:
1)沒有使用者宣告的複製建構函式
2)沒有使用者宣告的複製賦值運算子,
3)沒有使用者宣告的移動賦值運算子,
4)沒有使用者宣告的析構函式,和
5)移動建構函式不會被隱式定義為已刪除.
當類中某些成員的賦值運算子函式"="被delete掉(如unique_ptr,std::atomic等,或其他自定義型別),無法呼叫時,編譯器將無法提供預設移動建構函式
預設過載移動賦值操作符函式的行為與預設移動建構函式的行為類似,不再贅述
定義如下類a,用於標識呼叫了拷貝建構函式和移動建構函式
class同理,定義類ba a(a&&a)
};
class定義類c,包含類a和類bb b(b&&a)
};
class呼叫:c;
int輸出如下:main()
將類c中新增atomic型別成員,
class c上述**將無法編譯,報錯資訊如下:;
繼續使用9.1中類的定義,將main函式中的定義改為
int main()結果仍是
將類c中的atomic成員刪除,編譯通過,輸出結果為:
觀察q中的成員str和vec,都為空,說明預設的移動構造函式呼叫了成員的移動建構函式
將類b改為
class呼叫結果為b b(b&& a) = delete
;};
觀察q中的成員str和vec,str的值為123456,vec的size為100。說明只要乙個成員未提供移動建構函式,則編譯器生成的預設移動建構函式中,將對所有成員都呼叫拷貝建構函式,不呼叫移動建構函式,即使其他成員宣告了該函式
C 編譯器為類自動生成的函式
我們可以構建乙個空類,class empty 儘管沒有定義任何函式,但我們可以通過以下方式使用這個類 empty e1 empty e2 e1 e2 e1 因為當編譯器發現你用上述方式使用這個類而卻在類宣告中沒有定義一般建構函式 非複製建構函式 複製建構函式 賦值操作符過載函式和析構函式時,會自動為...
拒絕編譯器自動生成的函式
編譯器自動的函式 有些場景中需要拒絕這些編譯器自動生成的函式,可以通過下列方法,定義uncopyable類並繼承它。拒絕使用編譯器生成的函式 class uncopyable uncopyable private 拒絕copy uncopyable const uncopyable 在這裡宣告,不用...
C 空類編譯器自動生成的6個成員函式
在c 中,編譯器會為空類提供哪些預設成員函式?分別有什麼樣的功能呢?對於空類,編譯器不會生成任何的成員函式,只會生成1個位元組的佔位符。有時可能會以為編譯器會為空類生成預設建構函式等,事實上是不會的,編譯器只會在需要的時候生成6個成員函式 乙個預設的建構函式 乙個拷貝建構函式 乙個析構函式 乙個賦值...