默認(rèn)構(gòu)造函數(shù)合成
C++編譯器在其需要的時(shí)候嗡善,會(huì)為類合成默認(rèn)構(gòu)造函數(shù)渡蜻,以便用來執(zhí)行編譯器所需的操作术吝。所謂的需要,包含以下情況:
- class中沒有默認(rèn)構(gòu)造器茸苇,但是內(nèi)部包含有默認(rèn)構(gòu)造器的成員排苍。
C++編譯器會(huì)在構(gòu)造器被調(diào)用時(shí)合成一個(gè)構(gòu)造函數(shù)。如果這個(gè)構(gòu)造函數(shù)不復(fù)雜学密,則會(huì)以inline的形式完成淘衙,如果比較復(fù)雜,則會(huì)以explicit non-inline static的形式完成腻暮。合成的構(gòu)造函數(shù)將會(huì)調(diào)用成員的默認(rèn)構(gòu)造函數(shù)彤守,以便完成對(duì)默認(rèn)構(gòu)造函數(shù)調(diào)用的保證。如果程序員提供了默認(rèn)構(gòu)造函數(shù)哭靖,編譯器則會(huì)對(duì)默認(rèn)構(gòu)造函數(shù)進(jìn)行擴(kuò)充具垫,在執(zhí)行用戶指定代碼之前,調(diào)用成員的默認(rèn)構(gòu)造函數(shù)试幽。如果存在多個(gè)擁有默認(rèn)構(gòu)造函數(shù)的成員做修,編譯器則會(huì)按照成員定義的順序,依次調(diào)用成員的構(gòu)造函數(shù)抡草。 - class中沒有默認(rèn)構(gòu)造函數(shù),但是基類中包含默認(rèn)構(gòu)造函數(shù)蔗坯。
C++編譯器會(huì)合成默認(rèn)構(gòu)造函數(shù)或擴(kuò)展已有構(gòu)造函數(shù)康震,調(diào)用基類的默認(rèn)構(gòu)造函數(shù)。 - class中帶有虛方法或繼承自虛基類宾濒。
C++編譯器會(huì)合成默認(rèn)構(gòu)造函數(shù)或擴(kuò)展已有構(gòu)造函數(shù)腿短,處理vptr信息和虛基類信息。同時(shí)绘梦,會(huì)生成class對(duì)應(yīng)的vtbl橘忱。
說白了,編譯器合成默認(rèn)構(gòu)造函數(shù)卸奉,主要用于達(dá)到如下兩個(gè)目的:
1.調(diào)用成員和基類的默認(rèn)構(gòu)造函數(shù)钝诚,以便實(shí)現(xiàn)語(yǔ)言對(duì)于OO的承諾。
2.初始化虛函數(shù)機(jī)制和虛基類機(jī)制所需數(shù)據(jù)榄棵,以便支持對(duì)應(yīng)的函數(shù)特性凝颇。
拷貝構(gòu)造函數(shù)
拷貝構(gòu)造函數(shù)主要應(yīng)用于以下三種情況:
- 對(duì)一個(gè)對(duì)象做顯式的賦值操作潘拱。
- 將一個(gè)對(duì)象作為實(shí)參傳遞。
- 函數(shù)返回一個(gè)對(duì)象拧略。
如果class中沒有提供默認(rèn)的拷貝構(gòu)造函數(shù)芦岂,則會(huì)執(zhí)行default memberwise initialization,也就是把每一個(gè)內(nèi)建的或派生的數(shù)據(jù)成員的值垫蛆,從某個(gè)對(duì)象拷貝到另一個(gè)對(duì)象中禽最。拷貝的過程中不會(huì)拷貝類成員對(duì)象袱饭,而是以遞歸的方式實(shí)行類成員對(duì)象的拷貝川无。
如果class中沒有提供默認(rèn)的構(gòu)造函數(shù),則編譯器會(huì)按需生成默認(rèn)的拷貝構(gòu)造函數(shù)宁赤。合成的拷貝構(gòu)造函數(shù)主要用于調(diào)用成員對(duì)象的拷貝構(gòu)造函數(shù)舀透、基類的拷貝構(gòu)造函數(shù),以及處理虛方法表指針及虛基類指針决左。
初始化列表
使用場(chǎng)景:
- 當(dāng)初始化一個(gè)引用類型的成員時(shí)愕够。
- 當(dāng)初始化一個(gè)常量成員時(shí)。
- 當(dāng)調(diào)用基類的有參構(gòu)造方法時(shí)佛猛。
- 當(dāng)調(diào)用成員的有參構(gòu)造方法時(shí)惑芭。
編譯器在處理初始化列表時(shí),會(huì)按照成員在class中的聲明順序進(jìn)行處理继找,在用戶定義的代碼之前安插初始化操作遂跟。