C++ 定義抽象數(shù)據(jù)類型
構造函數(shù)
每個類都分別定義了它的對象被初始化的方式,類通過一個或幾個特殊的成員函數(shù)來控制器對象的初始化過程,這些函數(shù)叫做構造函數(shù)。構造函數(shù)的任務就是初始化類對象的數(shù)據(jù)成員,無論何時只要類的對象被創(chuàng)建,就會執(zhí)行構造函數(shù)。
構造函數(shù)是一個比較復雜的問題我們后面還會提到。
構造函數(shù)的名字和類名相同,和其他函數(shù)不一樣的是,構造函數(shù)沒有返回類型,除此之外類似于其他函數(shù),構造函數(shù)的形參可以有參數(shù)列表和函數(shù)體。類可以包含多個構造函數(shù),同時這些構造函數(shù)必須在參數(shù)數(shù)量或類型上有區(qū)別。
不同于其他成員函數(shù),構造函數(shù)不能被聲明成const。當我們創(chuàng)建類的一個const對象時,知道構造函數(shù)完成初始化對象才獲得常量屬性,所以構造函數(shù)在const對象的構造過程中可以寫入。
合成的默認構造函數(shù)
我們之前的Sales_data沒有定義任何的構造器,但是他們還是執(zhí)行了初始化,所以我們知道他執(zhí)行了默認初始化,類通過一個特殊的構造函數(shù)來控制默認初始化過程,這個函數(shù)叫做默認構造器,默認構造器無需任何實參。
編譯器創(chuàng)建的構造函數(shù)又稱為合成的默認構造函數(shù),對于大多數(shù)類來說這個構造器按照以下規(guī)則初始化類的數(shù)據(jù)成員
1 如果存在類內初始值,用它來初始化成員
2 否則默認初始化該成員
某些類不能依賴于合成的默認構造函數(shù)
編譯器只有發(fā)現(xiàn)類中沒有任何構造函數(shù)時才會使用默認構造函數(shù),一旦我們定義了其他的構造函數(shù),那么除非我們再定義一個默認構造函數(shù),否則類將沒有構造函數(shù)。
如果定義在塊中的內置類型或復合類型(例如指針和數(shù)組)的對象被默認初始化,則他們的指是未定義的。該準則同樣適用于默認初始化的內置類型成員,因此含有內置類型或復合類型成員的類應該在類的內部初始化這些成員,或者定義一個自己的默認構造函數(shù),否則可能得到未定義的值。
如果類中包含一個其他類類型的成員,且這個成員沒有默認構造函數(shù),那么編譯器無法初始化該成員。
定義構造函數(shù)
對于Sales_data來說我們使用下面參數(shù)定義四個不同的構造函數(shù)
1 一個istream&,從中讀取交易信息
2 一個const string&,表示isbn編號,一個unsigned表示銷售圖書的數(shù)量和一個double表示圖書的價格
3 一個const string&表示isbn編號,編譯器將賦予其他成員默認值
4 一個空參數(shù)列表(即默認構造函數(shù)),既然我們定義了其他構造函數(shù),那么我們必須定義默認構造函數(shù)。
=default的含義
首先該構造函數(shù)不接受任何實參,所以是一個默認構造函數(shù),我們定義這個構造函數(shù)的目的僅是我們既需要其他形式的構造函數(shù)有需要默認的構造函數(shù),我們希望這個函數(shù)的作用完全等同于之前使用的合成的默認構造函數(shù)。
在C++11中,=default既可以和聲明一起出現(xiàn)在類的內部,也可以作為定義出現(xiàn)在類的外部,如果=default出現(xiàn)在類的內部,則默認構造函數(shù)時內聯(lián)的,如果在外部則不是內聯(lián)的。
構造函數(shù)初始值列表
這兩個定義中出現(xiàn)了新的部分,即冒號到括號的部分,我們把他稱為構造函數(shù)初始值列表,他負責為新創(chuàng)建的對象一個或幾個數(shù)據(jù)成員賦初值,例如第一個定義,會將s的值賦給bookNo,同時隱式的將unsigned和double本應的初始值賦值給他們。
注意:構造函數(shù)不應該輕易覆蓋掉類內的初始值,除非新賦的值于原值不同。如果你的編譯器不支持類內初始值,則所有構造函數(shù)都應該顯式的初始化每個內置類型的成員。
在類的外部定義構造函數(shù)
當我們在類外定義構造函數(shù)時,必須指明該構造函數(shù)是哪個類的成員,我們第一個Sales_data就是用來指明是哪個類的構造函數(shù)。