我讀C++ Primer - 類

類是C++ 最基本的特性。類允許我們爲自己的應用定義新類型,從而使得程序更加簡潔且易於修改。

類的基本思想是數據抽象封裝。數據抽象是一種依賴於接口和實現分離的編程技術。封裝實現了接口與實現的分離。


1  定義類

定義在類內部的函數是隱式的inline 函數。

成員函數通過一個名爲this 的額外的隱式參數來訪問調用它的那個對象。

常量對象,以及常量對象的引用或指針都只能調用常量成員函數。

類的作者常常需要一些輔助函數,儘管這些函數定義的操作從概念上來說是屬於類的接口的組成部分,但他們不屬於類本身,可以聲明爲friend 函數。

構造函數:類通過一個或幾個特殊的函數來控制其對象的初始化過程。無論何時只要類的對象被創建,就會執行構造函數。

如果自己沒有定義構造函數,編譯器會給我們生成一個默認構造函數。而一旦自己聲明瞭任何一個構造函數,都不會有默認構造函數。

合成的默認構造函數的初始化成員規則:如果類內有初始值,用它來初始化成員,否則,默認初始化該成員。遇到複合類型其值爲未定義。合成的默認構造函數只適合非常簡單的類,因此最好自己聲明一個默認構造函數。

Sales_data() = default;
表示我們既需要其他形式構造函數,也需要默認構造函數,此時,編譯器會生成一個默認構造函數。

Sales_data(const string& s,unsigned n) : bookNo(s), units_sold(n){}
新出現的部分是構造函數初始化列表。
其他重要的如拷貝,賦值和析構,如果我們沒有定義,編譯器會合成一個版本。但是當類需要分配類對象之外的資源是,常常會失效,所以最好自己定義這些函數。


2  訪問控制

類與結構體的區別是,struct 中,定義在第一個訪問說明符之前的成員是public, class相反,是private。

友元:類可以允許其他類或者函數訪問它的非公有成員,就是令其他類或函數成爲它的友元。友元不是類的成員,所以不受所在區域的訪問限制的約束。一般來說,最好在類定義開始或者結束前的位置集中聲明友元。

友元的聲明僅僅指定了訪問的權限,而不是普通意義上的函數聲明,必須在友元聲明之外再專門對函數進行一次聲明。

封裝的好處:確保用戶代碼不會無意間破壞封裝對象的狀態;被封裝的類的具體實現細節可以隨時改變,無需調整用戶級別的代碼。

3  類的其他特性

內聯函數:建議在函數聲明和定義的地方都說明inline。

可變數據成員:可以修改類的數據成員,不管是不是在const 成員函數內。定義前加 mutable 關鍵字。

設計良好的C++ 代碼常常包含大量類似於 “do_display” 的小函數,通過調用這些函數,可以完成一組其他函數的實際工作。

友元:除了友元函數,還可以聲明友元類。注意:友元關係不存在傳遞性。友元函數使用之前必須在外部聲明。


4  類的作用域

每個類都會定義自己的作用域。作用域外,普通的數據和函數成員只能由對象,引用或者指針使用成員訪問運算符來訪問,類類型成員通過作用域運算符訪問。

類型名的定義(如 typedef) 通常出現在類的開始處,這樣就能確保所有使用該類型的成員都出現在類名的定義之後。


5  構造函數再探

如果沒有在構造函數的初始化列表中顯式的初始化成員,則該成員將在構造函數體之前執行默認初始化。這會影響效率。

如果成員是const,引用,或者某種未提供默認構造函數的類類型,必須通過構造函數初始化列表爲這些成員提供初值。

初始化的順序與在類定義中出現的順序一致。

C++ 11 新加了委託構造函數。一個委託構造函數使用它所屬類的其他構造函數執行它自己的初始化過程,如:

Sales_data(const string& s,unsigned n) : bookNo(s), units_sold(n){}
Sales_data() : Sales_data("",0) {} 
如果構造函數只接受一個實參,它實際上定義了轉換爲此類類型的隱式轉換機制。編譯器只會自動的執行一步類型轉換。

防止類型轉換要在構造函數聲明前加上explicit。在類外定義時不能重複加此關鍵字。

explicit 構造函數只能用於直接初始化,不能用於拷貝初始化,如:

Sales_data item1(null_book);   //直接初始化
sales_data item2 = null_book; //錯誤,拷貝初始化


6  類的靜態成員

類的static 靜態成員只與類本身直接相關,而不是與類的各個對象保持關聯。

類靜態函數不能聲明成 const 的,不包含this 指針。

可以通過類的對象,引用或者指針來訪問靜態成員,成員函數不用通過作用域運算符就能直接使用靜態成員。

在類的外部定義靜態成員時,static 不能重複出現。

靜態數據成員不屬於任何對象,所以不能由類構造函數初始化,也不能在類內部初始化,必須在類的外部定義和初始化靜態成員。只能定義一次,可以把靜態數據成員的定義與其他非內聯函數的定義放在同一個文件中。

靜態數據成員是不完全類型,其類型可以是它所屬類的類型,而非靜態數據成員則受到限制,只能聲明成它所屬類的指針或引用。另一個區別是,可以使用靜態數據成員作爲默認實參。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章