天天看點

C++ Primer 學習筆記_52_類與資料抽象 --構造函數【下】類

二、預設實參與構造函數

一個重載構造函數:

可以通過給string初始化式提供一個預設實參将這些構造函數組合起來:

是以:

都将執行為其string形參接受預設實參的那個構造函數。

【最佳實踐】

     我們更喜歡使用預設實參,因為它減少代碼重複!

三、預設構造函數

   隻要定義一個對象時沒有提供初始化式,就使用預設構造函數。為所有形參提供預設實參的構造函數也定義了預設構造函數。

1、合成的構造函數

    一個類哪怕隻是定義了一個構造函數,編譯器也不會再生成預設構造函數。這條規則的根據是,如果一個類在某種情況下需要控制對象初始化,則該類很可能在所有情況下都需要控制。

    隻有當一個類沒有定義構造函數時,編譯器才會自動生成一個預設構造函數。

    如果類包含内置或複合資料類型的成員,則該類不應該依賴于合成的預設構造函數。他應該定義自己的構造函數來初始化這些成員!

    如果每個構造函數将每個成員設定為明确的已知狀态,則成員函數可以區分空對象和具有實際值的對象。

2、類通常定義一個預設構造函數

   假定有一個nodefault類,它沒有定義自己的預設構造函數,卻有一個接受一個string實參的構造函數。因為該類定義了一個構造函數,是以編譯器将不合成預設構造函數。nodefault沒有預設構造函數,意味着:

    1)具有nodefault成員的每個類的每個構造函數,必須通過傳遞一個初始的string值給nodefault構造函數來顯式地初始化nodefault成員。

    2)編譯器将不會為具有nodefault類型成員的類合成預設構造函數。如果這樣的類希望提供預設構造函數,就必須顯式地定義,并且預設構造函數必須顯式地初始化其nodefault成員。

    3)nodefault類型不能用作動态配置設定數組的元素類型。

    4)nodefault類型的靜态配置設定數組必須為每個元素提供一個顯式的初始化式。

    5)如果有一個儲存nodefault對象的容器,例如vector,就不能使用接受容器大小而沒有同時提供一個元素初始化式的構造函數。

實際上,如果定義了其他的構造函數,則提供一個預設構造函數幾乎總是對的。通常,在預設構造函數中給成員提供的初始值指出該對象是空的!

3、使用預設構造函數

   使用預設構造函數定義一個對象的:

或者是:

編譯器建立并初始化一個sales_item對象,然後用它來按值初始化myobj。但是不能是下面這種形式:

四、隐式類類型轉換

為了定義到類類型的隐式轉換,需要定義合适的構造函數。

    可以使用單個實參來調用的構造函數定義了從形參類型到該類型的一個隐式轉換!

我們以前定義的兩個構造函數:

在這兒其實每個構造函數都定義了一個隐式轉換!!!是以,在期待sales_item類型對象的地方,可以使用一個string或者istream:

   該函數期待一個sales_item對象作為實參。編譯器使用接受一個 string或 istream的sales_item構造函數生成一個新的sales_item對象。新生成的(臨時的)sales_item被傳遞給same_isbn。

   由于這個sales_item對象是一個臨時對象。一旦same_isbn結束,就不能再通路它。實際上,我們構造了一個在測試完成後被丢棄的對象。這個行為幾乎肯定是一個錯誤。

1、抑制由構造函數定義的隐式轉換

   可以通過将構造函數聲明為explicit,來防止在需要隐式轉換的上下文中使用構造函數:

調用:

說明:explicit隻能用于類内部的構造函數的聲明:

2、為轉換而顯式地使用構造函數

顯式使用構造函數隻是終止了隐式地使用構造函數。任何構造函數都可以用來顯式地建立臨時對象!

    通常,除非有明顯的理由想要定義隐式轉換,否則,單形參構造函數應該為explicit。将構造函數設定為explicit可以避免錯誤,并且當轉換有用時,使用者可以顯式地構造對象。

五、類成員的顯式初始化

    對于沒有定義構造函數并且其全體資料成員均為public的類,可以采用與初始化數組元素相同的方式初始化其成員:

缺點:

    1)要求類的全體資料成員都是public。

    2)将初始化每個對象的每個成員的負擔放在程式員身上。這樣的初始化是乏味且易于出錯的,因為容易遺忘初始化式或提供不适當的初始化式。

    3)如果增加或删除一個成員,必須找到所有的初始化并正确更新。

    定義和使用構造函數幾乎總是較好的。當我們為自己定義的類型提供一個預設構造函數時,允許編譯器自動運作那個構造函數,以保證每個類對象在初次使用之前正确地初始化。

繼續閱讀