認識C++的對象
1.1初識c++的函數和對象
C++語言兼容C語言,這一語句在C++中則等效爲聲明一個整數對象。
即只要換一下思維模式,就可以通過C語言的變量認識C++的對象。
在C++中則稱爲結構對象。
1.混合型語言
C++程序以.CCP作爲文件擴展名,並且必須有一個且只能有一個名爲main(不是C++的關鍵字)的主函數。
2靈活的註釋方式
C++除沿用C語言的從“、/*”開始,直到“*/”結束的註釋方式之外,引入了更靈活的方式“//”,註釋的有效範圍從“//”至本行結束。
3.使用輸出和輸入對象
C++將數據從一個對象流向另一個對象爲“流”。從流中獲取的數據的操作稱爲提取操作。
cin和cout都不是C++語言本身的定義的一部分,而是由C++的一套面向對象類體系提供支持並作爲C++標準程序庫的一員所以在使用它們之前需要在主函數前使用#include語句將其包含。C++標準備輸入輸入庫的頭文件時iostrean在程序中使用定義的方法。
4.使用命名空間
所謂的命名空間(namespace)是一種將程序庫名稱封裝起來的方法,它提高了程序的性能和可靠性。
若要在程序中使用cin和cout這兩個iosteam數的對象,不僅要包含iosteam頭文件,還得讓命名空間std內的名稱曝光這一條語句就是讓命名空間中的名稱曝光。
C++新標準就是將標準類庫的頭文件與一般的頭文件要(需要使用擴展名“.h)區分開來。當然,也可以自己定義符合標準
準庫頭文件,使用這種頭文件時,也需要有同時使用命名空間語言。
5.對象的定義及初始化
定義對象包括它命名並賦予它類據類型。
6.函數原型及其返回值
函數都需要有類型說明。int main()指出main是整數類型,返回值由return後面的表達式決定,且表達式的值必須與聲明函數的類型一致。
返回“0”值來表示main函數結束。如果函數確定不需要返回值,還可以用void標識,一旦使用void標識,函數體內就再需要使用return語句。
對無需返回值的函數將使用void的形式且不使用return語句。
C++函數有庫函數(標準函數)和自定義函數兩類。
C++程序使用變量的基本規則是:必須先聲明,後使用。
7 const修飾符和預處理程序
C語言一般使用宏定義“#define”定義常量,在C++中,建議使用const代替宏定義。
因爲被const修飾的變量的值在程序中不能被改變,所以在聲明符號常量時,必須對常量符號進行初始化,除非這個常量是用extern修飾的外部變量。
Const的用處不僅僅是在常量表達式中代替宏定義。如果一個變量在生存期中的值不會改變,就應該用const來修飾這個變量,以提高程序安全性。
C++語言預處理程序不是編譯程序的一部分,
爲了與一般的C++程序語句相區別,所以有預處理語句都以位於首行的符號“#”開始。預處理語句有3種,分別是宏定義、文件包含和條件編譯。
是使用雙眼號還是尖括號,其含義並不一樣。採用尖括號引用系統提供的的包含文件,C++編譯系統將首先在C++語言系統設定的目錄中尋找包頭文件,如果沒有找到,就到指定目錄中去尋找。採用雙引號引用自己定義的包含文件(一般都放在自己指定的目錄中),這將天通知C++編譯器在用戶當前目錄下火尋找包含文件。
8程序運行結果
9程序書寫格式
(1)括號緊跟在函數名後面,但在for和while後面,應用一個空格與左括號隔開以增加可讀性。
(2)數學運算符的左右各留意個空格,以與表達式區別。
(3)在表達參數時,逗號後面留個空格。
(4)在for、while和do…while語句中,合理使用縮進、一對花符號和空行。
(5)適當增加空行和程序註釋以增加可讀性。
(6)太長的程序行兩行或者幾行,並注意選取合適的分行和縮進位置。
1.2認識C++語言面向過程編程的特點
C語言是典型的面向過程的語言。因爲C++兼容了C語言,所以也可以使用C++編制面對過程的程序。
1.2.1使用函數重載
C++允許爲同一函數定義幾個版本,從而使一個函數名具有多種功能,這稱爲函數重載。
1.2.2 新的數據類型 及其注意事項
Void是無類型的標識符號,只能聲明函數的返回值類型,不能聲明變量。C++還比C語言多了bool(布爾)型。C++標準只限定int和short至少要有16位,而long至少32位,short不的長於int,int不得長於long。Visual C++ 6.0規定int使用4字節。
C++語言中的整數常量有4中類型:十進制常量、長整形常量、八進制常量和十六進字常量,並用前綴後綴進行分類標識。
C++語言與C語言一樣,也使用轉義序列。
1.2.3 動態分配內存
1.2.4引用
數據類型&別名=對象名;
“Int& a=x;”、“int & a=x;”是等效的
所謂“引用”就是就是將一個新的標識和一塊已經存在的存儲區域的相關聯。
(1)引用實際上就是變量的別名,使用引用就如同直接使用變量一樣。引用與變量在使用的形式上是完全一樣的, 引用只是作爲一種標識的手段,不能直接聲明對數組的引用,也不能聲明引用的引用。
1.2.5 對指針使用const 限定符
可以使用const限定符強制改變訪問權限。
1左值和右值
左值是指某個對象的表達式。
2指向常量的指針
指向常量的指針式在飛常量指針前聲明前面使用const,
3 常量指針
把const限定符號放在*號的右邊,使指針本身成爲一個const指針。
4指向常量的常量指針
可以聲明指針和指向對向的對象都不能改動的“指向常量的常量指針”,這是必須要初始化指針。
1.2.6 泛型算法應用普通數組
數組不能作爲整體輸出。
入STL庫提供的泛型算法,則可大大簡化數組操作。所謂泛型算法, 就是提供的操作與元素類型無關。
對數組進行排序爲升冪或降冪,默認爲升冪排序。要輸出數組的內容、對數進行升冪排序、反轉數組的內容、複製數組的內容等操作,需要包頭文件。要對數組進行降冪排序和檢索,需要包頭文件。
假設一堆數組a和b的長度均爲Len,數據類型爲Type。
1數組內容反轉
2複製數組的內容
3數組升冪排序
4數組降冪排序
5查找數組內容
6輸出數組的內容
1.2.7數據的簡單輸入輸出格式
1.3程序的編輯、編譯和運行的基本概念
用C++語言寫程序稱爲源程序,源程序必須經過C++編譯翻譯成機器語言才能執行。
(1)先使用編輯器編輯一個C++程序mycpp.cpp,又稱其爲C++的源程序。
(2)然後使用編譯器對這個C++程序進行編譯,產生myccp.obj。
(3)再使用連接程序(又稱Link),將mycpp.obj變成mycpp.exe文件。
第二章
從結構到類的演變
2.1結構的演化
類是從結構演變而來的,開始稱爲“帶類的C”。
2.1.1結構發生質的演變
1函數與數據共存
C++首先允許結構中可以定義函數,這些函數稱爲成員函數。如果將原來的結構成員稱爲數據成員的話,可以使用如下的形式描述:
Struct結構名{
數據成員
成員函數
};
最後一條語句則是直接使用數據成員,這稱作結構point的共有(public)性質。
2封裝性
如果在定義結構時,將數據成員使用private關鍵定義,則產生封裝性。
沒有使用private定義的成員函數,默認爲public。
這就變成了具有類的性質的結構。只是類使用關鍵字class定義,它默認的是private。
2.1.2使用構造函數初始化結構對象
構造函數名 對象名(初始化參數);
2.2從結構演變一個簡單的類
2.3面向過程與面向對象
所謂“面向過程”,就是不必瞭解計算機的內部邏輯,而把精力主要集中在對如何求解問題的算法邏輯和過程的描述上,通過編寫程序把解決問題的步驟告訴計算機。
(1)要求開發人員按計算機的結構去思考,而不是按解決的問題結構去思考。
(2)開發員必須在機器模型(解空間)和實際問題模型(問題空間)之間進行對應。
結構化程序設計使用的是功能抽象,面向對象程序設計不僅能進行功能抽象,而且能進行數據抽象。
面向對象的程序設計方法不是以函數過程和數據結構中心,而是以對象代表求解問題的中心環節。
軟件開發是給定問題求解的過程。從認識論的角度看,可以爲兩項主要活動:認識與描述。
2.4 C++面向對象程序設計的特點
面向對象的程序的設計具有抽象、封裝、繼承和多肽型等關鍵要要數。
2.4.1 對象
C++可使對象名、屬性和操作三要素來描述對象。對象名用來標識一個具體對象。用數據來標是對象的屬性,一屬性就是描述對象靜態的特徵的一個數據項。
數據稱爲數據成員,函數稱爲函數成員。
C++中的對象是系統中用來描述客觀事物的一個實體,是構成系統的一個基本單位。
2.4.2 抽象和類
2.4.3 封裝
將類封裝起來,也是爲保護類的安全。所謂的安全,就是限制使用類的屬性和操作。
對象的操作分爲內部操作和外部操作。內部操作只供對象的其他操作使用,不對外部提供。外部操作對外部提供一個消息接口,通過這個接口接受對象外部消息併爲之提供操作(服務)
封裝就是把對象的屬性和操作結合稱一個獨立的系統單元,並緊可能的隱蔽對象的內部細節。
2.4.4 繼承
繼承是一個類可以得另一類特性的機制,繼承支持層次概念。
2.4.5 多態性
不同的對象可以調用相同的函數,但可導致完全不同的行爲的現象稱爲多態性。
2.5 使用類和對象
2.5.1使用string的對象
在程序中可以使用string類定義存儲字符串的對象。
如果string的對象str的內容爲“ab”,則str[0]=‘a’,str[1]=‘b’。
Strl。Size()的值爲單詞‘good’的長度。
2.5.2 使用string類的典型成員函數實例
String對象是通過調用成員函數實現操作,從而提供對象的行爲或消息傳遞的。
2.5.3 使用complex對象
C++標準程序庫提供complex類定義複數對象。在程序中包含這個類的頭文件:
Complex類是一個模版類,所謂模版,意思是說,它可以定義多種數據類型的複數。
第三章
函數和函數模板
3.1函數的參數及其傳遞方式
C語言函數參數的傳遞方式只有傳值一種,傳值又分爲傳變量和傳變量地址值兩種情況。
參數傳遞中不要混淆傳地地址值和傳地址的區別。傳地址的是值,不是地址;傳地址傳的是地址不是地址值。
在設計函數參數是,可以使用“對象”、“對象指針”和“對象引用”作爲參數。
3.1.1對數作爲函數參數
將對象作爲函數參數,是將實參對象的值傳遞給形參對象,這種傳遞是單向的。形參擁有實參對象的備份,當在函數中改變形參的值時,改變的是這個備份中的值,不會影響原來實參的值。
直接使用基本數據類型的對象,或使用和結構的對象作爲參數,均是傳值的方式。不能將數組的值作爲函數參數,但可以將數組的地址作爲參數,即使用指針作爲參數。
3.1.2對象指針作爲函數參數
將指向對象的指針作爲函數參數,形參是對象指針(指針可以指向對象的地址),實參是對象的地址值。
3.1.3引用作爲函數參數
可以使用“引用”作爲函數的參數“引用形參”。這時函數並沒有對形參對象初始化,即沒有指定形參對象是哪個對象別名。
虛實結合是把實參對象的地址傳給形參對象,使形參對象的地址取實參對象的地址,從而使形參對象和實參對象共享同一個單元。這就是地址傳遞方式。爲了便於理解,可以簡單地認爲是把實參對象的名字傳給引用對象,使引用對象稱爲實參對象的別名。
在說明引用參數時,不需要提供初始值,其初始值在調用時有實參對象提供。
3.1.4默認參數
默認參數就是不要求程序員設定該參數,而又編譯在需要時給該參數賦默認值。當程序員需要傳遞特殊值時,必須顯式地指明。默認參數是在函數原型中說明的,
3.1.5使用const保護數據
用const修飾傳遞函數,意思是通知函數,它只能使用參數而無權修改它。
3.2深入討論函數返回值
C++函數的返回值類型可以是除數組和函數以外的任何類型。非void類型的函數必須向調用者返回一個值。數組只能返回地址。
因此不能將函數內部的局部對象作爲函數的返回值。
3.2.1返回引用的函數
3.2.2返回指針函數
3.2.3返回對象的函數
3.2.4函數返回作爲函數的參數
3.3內聯函數
使用關鍵字inline說明函數稱內聯函數。在C++中,除具有循環語句、switch語句的函數不能說明爲內聯函數外,其他函數都可以說明爲內聯函數。使用內聯函數能加快程序執行速度,但如果函數體語句多,則會增加程序代碼的大小。使用小的內聯函數在代碼速度和大小可以取得折衷,
3.4函數重載和默認參數
函數重載可是一個函數名具有多功能,即具有“多種形態”,稱這種特性爲多態性。
從函數原型可見,它們的區別一是參數類型不同,二是參數不同。
使用默認參數就不能對少於參數個數的函數進行重載。
3.5函數模板
1引入函數模板
因爲字母T能使人聯想到它是單詞Type的第一個字母,所以一般選T作爲標識符號來標識類型參數,即參數名可以任意挑選的。規定模板一template關鍵字和一個形參表開頭。
2函數模板的參數
函數模板名<模板參數>(參數列表)
函數模板(參數列表)
3 使用顯式規則和關鍵字typename
另外,C++還專門定義一個僅僅用在模板中的關鍵字typename,它的用途之一是代替template參數列表中的關鍵之class。
第四章
類和對象
4.1類及其實例化
4.1.1定義類
類也要先聲明後使用;不管聲明的內容是否相同,聲明同一個名字的兩個類是錯誤的,類是具有惟一標識的實體;在類中聲明的任何成員不能使用extern、auto和register類關鍵字進行修飾;類中聲明變量屬於該類,在某些情況下,變量也可以被該類的不同實例所共享。
1聲明類
Private:私有數據和函數
Public:公有數據和函數
Protected:保護數據和函數
如果沒有使用關鍵字,則所有成員默認聲明爲private權限。其中“∷”是作用域運算符,“類名”是成員函數所屬類的名字,“∷”用於表明其後的成員函數是屬於這個特定的類。
3數據成員的賦值
不能再體內給數據成員賦值
4.1.2使用類的對象
(1)類的成員可以直接使用自己類的私有成員
(2)類外面的函數不能直接訪問類的私有成員
(3)類外面的函數只能通過類的對象使用該類的共有成員函數。
(4)對象A和B的成員函數的代碼一樣,A和B兩個對象的區別是屬性的取值。
4.1.3 數據封裝
C++對其對象的數據成員和數據函數的訪問控制權限來限制的。
C++通過類實現數據封裝
4.2構造函數
4.2.1默認構造函數
一旦程序定義了自己的構造函數,系統就不在提供默認函數。
因爲每個元素對象均需要用一次默認構造函數來自己初始化,所以必須要求有一個默認構造函數。如果程序中定義了有參數的構造函數,又存在需要先建立對象數組後進行賦值操作的情況,則必須爲它定義無參數的結構函數。
4.2.2 定義構造函數
1構造函數的定義和使用方法
構造函數的參數在排列時無順序要求,只要保證相負對應即可。可以使用默認參數或重載。
2自動調用構造函數
4.2.3構造函數和運算符new
運算符new用於建立生存期可控對象,new返回這個對象指針。
當使用new建立一個動態對象時,new首先分配足以保存point類的一個對象所需要的內存。
4.2.4 構造函數的默認參數
4.2.5複製構造函數
這是一類特殊而且重要的函數通常用於使用已有的對象來建立一個新對象。
對象建立新對象,譯爲拷貝構造函數。
4.3析構函數
在對象消失時,應使用析構函數釋放構造函數分配的內存。
4.3.1定義析構函數
因爲調用析構函數也是由編譯器來完成的所以編譯器必須總能知道應調用哪個函數析構函數的前面加上一個“~”號。
析構函數不能指定參數,但是可以顯式地說明void,
一個類也這能定義一個析構函數且不能指明參數,
4.3.2 析構函數和運算符delete
4.3.3默認析構函數
4.4調用複製構造函數的綜合實例
4.5成員函數重載及默認參數
4.6this指針
4.7一個類的對象作爲另一類的成員
距形類Rectangle的屬性需要一個座標點及長和寬。一個point的對象恰好可以作爲矩形的頂點座標,即Rectangle可以使用point的一個對象作爲數據成員。
4.8類和對象的性質
(1)同一類的對象之間可以相互賦值。
(2)可使用對象數組。
(3)可使用指向對象的指針,使用取地址運算符&將以個對象的地址置於該指針中。
(4)對象用作函數參數。
(5)對象作爲參數時,可以使用對象、對象引用和對象指針。
(6)一個對象可以做另一個類的成員。
4.8.2類的性質
1使用類的權限
1假設聲明瞭point類,爲了簡單具體,討論數據成員爲私有,成員函數爲公有情況。
(1)類本身成員函數可以使用類所以成員(私有和公有成員)。
(2)類的對象只能訪問公有成員函數
(3)其他函數不能使用類的私有成員,也不能使用公有成員函數,它們只能通過類的對象使用公有成員函數。
(4)雖然一個類可以包含另一個類的函數對象,但這個類也只能通過被包含類的對象使用那個累的成員函數,通過成員函數使用數據成員。
2不完全類聲明
使用struct關鍵字設計類時,struct與class相反,struct的默認控制權限是public。一般建議不用struct設計類
4.9面向對象的標記圖
4.9.1類對象的UML標記圖
類使用短式長式兩種方式表示。短式僅用1個含義類名的長方框表示。
4.9.2對象的結構與連接
只有定義和描述了對象之間的關係,各個對象才能構成一個整體的、有機的系統模型,這就是對象的結構域連接關係。對象結構是指對象之間的分類(繼承)關係和組成(集合)關係,統稱爲關聯關係。
1分類關係及其表示
2對象組成關係及其表示
組成關係說明的結構是整體與部分關係。C++中最簡單的是包含關係,
C++語言中的“聚合”隱含了兩種實現方式,第1種方式獨立地定義,可以屬於多個整體對象,
第2中方式是用以個對象作爲一種廣義的數據類型來定義整體對象的一個屬性,
3實例連接及其表示
一對一、一對多和多對多3種連接方式。
4消息連接及其表示
消息連接描述對象之間動態關係
消息連接時有方向的,使用一條帶箭頭的實線表示從消息的發送者指向消息的接受者。
4.9.3使用實例
1 Line類包含point類
2 Line類的繼承point類
4.9.4 對象、類和消息
對象的行爲是定義在對象屬性上的一組操作的集合。操作(函數成員)是響應消息而完成的算法,表示對象內部實現的細節。對象的操作和體現了對象的行爲能力。
對象的屬性和行爲是對象定義組成的要數,
(1)有一個狀態,由與其關聯的屬性值集合所表徵
(2)惟有一標識名,可以區別於其他對象。
(3)有一組操作方法,每個操作決定對象的一種行爲。
(4)有一組狀態只能被自己的行爲所改變。
(5)對象的操作包括自身操作(施加與自身)和施加於其他對象的操作。
(6)對象之間以消息傳遞的方式進行通信。
(7)一個對象的成員可以是一個對象。
消息是向對象發出的服務請求,它是面向對象系統中實現對象間的通信和請求任務的操作。
對象傳遞的消息一般有3部分組成:接收對象名、調用操作名和必要的參數。
4.10面向對象編程的文件規範
實現放在.cpp文件中。在.cpp文件中
4.10.1編譯指令
所有的編譯指令以#開始,每條指令單獨佔用一行,同一行,同一行不能有其他編譯指令和C++語句。
1嵌入指令
2宏定義
#define的指令定義一個標識符串,在員程序中每次遇到該標識符時,編譯器均用定義的字符串替之。每行的行尾要加上一個方斜線,表示在宏定義繼續到下一行。
因宏定義有許多不安全因素,對需要使用無參數宏的場合,應該儘量使用const代替宏定義。
如果不想使其影響到程序的其他地方,可以在不再使用時用#undef刪除。
3條件編譯指令
條件編譯指令是#if、#else和#endif,它們構成類似於C++的if選擇結構,其中#endif表示一條指令結束
4defined操作符
關鍵字defined不是指令,而是一個預處理操作符。用於判定義個標識符是否已經被#defined定義。
條件編譯指令#ifdef和ifndef用於測試其後的標識符是否被define定義,如果已經被定義,則#ifdef測試爲真,#ifdef測試爲假,#ifindef測試爲真。
4.10.2在都文件中使用條件編譯
第五章
特殊函數和成員
5.1對象成員的初始化
如果初始初始化列表某項的參數函數表爲空,則列表相應的項可以省略
對象成員構造函數的調用順序取決於這些對象成員在類中的說明順序。
析構函數的調用順序與構造函數正好相反。
5.2靜態成員
簡單成員函數是指聲明函數不含const、volatile、static關鍵字的函數。如果類的數據成員或成員函數使用關鍵字static進行修飾,這樣的成員稱爲靜態成員或靜態成員函數,統稱爲靜態成員。
靜態數據成員能說明一次,如果在類中僅對靜態數據成員進行聲明,則必須在文件作用域的某個地方進行定義。在進行初始化時,必須進行成員名限定。
除靜態成員的初始化之外,靜態成員遵循類的其他成員函數所遵循的訪問限制,
由於數據隱蔽的需要,靜態數據成員通常被說明爲私有的,
通過成員限定訪問靜態成員,比使用對象名訪問靜態成員要好,因爲靜態成員是類的成員而不是對象的成員。
類中的任何成員都可以訪問靜態成員。因爲靜態成員函數沒有this指針,所以靜態成員函數只能通過對象名(或指向對象的指針)訪問該對象的非靜態成員。
(1)可以不指向某個具體的對象,只與類名連用。
(2)在沒有建立對象之前,靜態成員就已經存在。
(3)靜態成員爲類的成員,不是對象的成員。
(4)靜態成員爲該類的所有對象共享,它們被存儲於一個公用內存中。
(5)沒有this指針,所有除非顯式地吧指針傳給它們,否則不能存取類的數據成員。
(6)靜態成員函數不能被說明爲虛函數。
(7)靜態成員函數不能直接訪問非靜態函數。
關鍵字static聲明的類的對象,但要注意它的構造函數與析構函數的調用特點。
5.3友員函數
友員函數可以存取私有成員、公有成員和保護成員。
1.類本身的友元函數
2.將成員函數做有元
3.將一個類說明爲另一個類的友元
友元關係是不傳遞的即當說明類A是類B的友元,類B又是類C的友元時,
5.4 const對象
可以再使用const關鍵字定義數據成員和成員函數和修飾一個對象。一個const對象只能訪問const成員函數。
1常量成員
常量成員包括常量數據成員、靜態常數據和引用。靜態常數成員仍保留靜態成員特徵,需要在類外初始化。常數據成員和常引用只能通過初始化列表來獲得初值。
2常引用作爲函數參數
使用引用作爲函數參數,傳送的是地址。
3常對象
在對象名前使用const聲明常對象,但聲明是必須同時進行初始化,而且不能被更新。
4常成員函數
一個const對象可以調用const函數,但不能調用非const成員函數。Const放在函數聲明之前意味着返回值是常量,
爲了保證不僅聲明const成員函數,而且確定也定義爲const函數,程序員在定義函數時、必須重申const聲明。
普通對象可以使用全部成員函數,但常量對象只能使用常量函數。
5.5 數組和類
5.6指向類成員函數的指針
C++既包含指向類數據成員的指針,又包含指向成員函數指針。
類並不是對象,但有時可將其視爲對象使用。可以聲明並使用指向對象成員函數的指針。
5.7 求解一元二次方程
5.7.1 設計代表方程的類
5.7.2設計成員函數
1.設計構造函數
2.設計成員函數
5.7.3編程實現
1設計工程和文件
2頭文件
3實現類
5.7.4使用VC編制完整的文件
5.7.5 運行示範
第六章
繼承和派生
6.1繼承和派生的基本概念
類的派生和繼承是面向對象 程序設計方法和C++語言最重要的特徵之一
從一個活多個以前定義的類(基類)產生新類的過程稱爲派生類。
派生的新類同時也可以增加或者重新定義數據和操作,這就產生了類的層次性。
類的繼承是指派生類繼承基類的數據成員函數。
當從現有類中派生出新類是
(1)增加新成員
(2)重新定義已有的成員函數。
(3)改變基類成員的訪問權限。
6.2 單一繼承
6.2.1 單一繼承的一般形式
6.2.2派生類的構造函數和析構函數
構造函數(包括析構函數)是不被繼承的,所以一個派生類只能調用它的直徑基類的構造函數。當定義派生類的對象時,首先調用基類的機構函數,對基類成員進行初始化
6.2.3 類的保護成員
6.2.4訪問權限和賦值兼容規則
1公有派生和賦值兼容規則
(1)基類的公有成員在派生類中仍然是公有的。
(2)基本的保護成員在派生類中仍然是保護的。
(3)基類的不可以訪問的和私有的成員在派生類中也仍然是不可訪問的。
但是在派生類中,可以存在滴4種訪問級別:不可訪問(inaccessible)。
所謂賦值兼容規則是指在公有派生情況下,一個派生類的對象可以作爲基類的對象來使用的情況。
(1)派生的對象可以賦給基類的對象。
(2)派生類的對象可以初始化基類的引用。
(3)派生類的對象的地址可以賦給指向基類的指針。
2“isa”和“has-a”的區別
如果寫成類B公有繼承於類A,在可以使用A對象的讓任何地方,則類B的對象通信業能使用,因爲每一個類B的對象”“就是一個”類A的對象。
3公有繼承存取權限表
派生類一般都使用公有繼承。使用基類本身、派生類、對象和外部函數,對派生類而言,使用它的有派生類本身、對象和外部函數。
注意:靜態成員可以被繼承,這時,基類對象和派生的對象共享該靜態成員。
4私有派生
通過私有派生,基類的私有和不可訪問成員在派生類中是不可以訪問的,而公有和保護成員這時就成了派生類私有成員,派生類的對象不能訪問繼承的基類成員,必須定義公有函數作爲接口。
6.3多重繼承
6.4二義性激情支配規則
對基類成員的訪問必須是無二義性的,如使用一個表達式的含義能解釋爲可以訪問多個基類的成員,則這種對基類成員的訪問就是不確定的,稱這種訪問具有二義性。
6.4.1 作用域分辨和成員名限定
6.4.2 派生類支配基類的同名函數
6.5 典型問題分析
1派生類沒有使用基類的數據成員
2派生類支配基類的同名函數
3二義性
4友元和派生類
友元聲明與訪問控制無關。友元聲明在私有區域進行或在公有區域進行是沒有太大區別的。
第七章
類模板與向量
7.1類模板
7.1.1類模板基礎知識
1.類模板的成分及語法
Template<類模板參數>class類名{//類體};
2 類模板的對象
類模板也稱爲參數化
類名<模板實例參數類型>對象名(構造函數實例參數列表);
類名<模板實例參數類型>對象名;//默認或者無參數構造函數
Template<模板參數>
返回類型 類型<模板類型參數>∷成員函數名(函數參數列表){//函數體}
7.1.2類模板的派生於繼承
類模板也可以繼承,繼承的方法與普通的類一樣。聲明模板繼承之前,必須重新聲明類模板。模板類的基類和派生類都可以是模板(或非模板)類。
7.2 向量與泛型算法
在數組生存期內,數組的大學、小不會改變的。向量是一維數組的類版本,它與數組相似,其中的元素項是連續存儲的,但它和數組不同的是:向量中存儲元素的多少可以再運行中根據需要動態地增長或縮小。向量是類模板具有成員函數,
7.2.1定義向量列表
向量(vector)類模板定義在文件vector中,它提供4種構造函數,用來定義有各元素組成的列表。用length表示長度,數據類型用type表示,對象名爲name,
7.2.2泛型指針
“與操作對象的數據類型相互獨立”的算法稱爲泛型算法。
泛型算法提供了許多可用於向量的操作行爲,而這些算法和想要操作的元素類型無關。這是藉助一對泛型指針來實現的。
在向量中,泛型指針是在底層指針的行爲之上提供一層抽象化機制,取代程序原來的“指針直接操作方式”。
7.2.3 向量的數據類型
7.2.4 向量最基礎的操作方法
向量有許多成員函數用來提供不同的操作,
1訪問向量容量信息的方法
(1)Size():返回當前向量中已經放的對象個數。
(2)Max_size():返回向量可以可以容納最多的對象個數,一般是操作系統的尋址空間鎖能容納的對象個數。
(3)Capacity():返回無需再次分配內存就能容納的對象個數。
(4)Empty()當前向量爲空時,返回true值。
2訪問向量中對象的方法
(1)front()返回向量中的第1個對象。
(2)Back():返回向量中的最後一個對象。
(3)Operator[]:(size_type,n):返回向量中的第n+1個對象(下標爲n的向量元素)。
7.2.4向量最基礎的操作方法
7.3 出圈遊戲
1設計類
2主函數
3源程序
第八章
多態性和虛函數
8.1多態性
靜態聯編所支持的多態性稱爲編譯時的多態性。動態聯編所支持的多態性稱爲運行時的多態性,
8.1.1靜態聯編中的賦值兼容性及名字支配規律
8.1.2 動態聯編的多態性
如果讓編譯器動態聯編,也就是在編譯“point*P=&c;”語句時,只根據兼容性規則檢查它的合理性,也就是檢查是否符合“派生類對象的地址可以賦給基類的指針”的條件。至於“p->area()”
調用哪個函數,等程序運行到這裏時再決定。
就要使類point的指針p指向派生類函數area的地址。假設使用關鍵字virtual聲明point的類area函數,將這種函數稱爲虛函數。
當編譯系統編譯含有虛函數的類時,將爲它建立以個虛函數表,表中的每個元素都指向一個虛函數地址。編譯器爲類增加一個數據成員,這個數據成員是一個指向該虛函數表的指針,通常稱爲vptr。
虛函數的地址翻譯取決於對象的內存地址。編譯器爲含有虛函數的類的對象建立一個入口地址,這個地址用來存放指向虛函數表的指針vptr,然後按照類中的虛函數聲明次序,一一填入函數指針。
派生類能繼承基類的虛函數表,而且只要是和類同名(參數也相同)的成員函數,無論是否使用virtual聲明,它們都自動成爲虛函數。如果派生類沒有改寫基類的虛函數,則函數指針調用基類的虛函數。如果派生改寫了基類的函數,編譯器將重新爲派生類的虛函數建立地址,函數指針會調用改寫過的虛函數。
虛函數的調用規則是:根據當前對象,優先調用對象本身的虛成員函數。
8.2 虛函數
一旦基類定義了虛函數該基類的派生類中的同名函數也自動成爲虛函數。
8.2.1 虛函數
函數只能是類中的一個成員函數,但不能使靜態成員,
8.2.2 虛函數實現多態的條件
關鍵字virtual指示C++編譯器對調用虛函數進行動態聯編。這種多態性是程序運行到需要的語句處才動態確定的,所以稱爲運行時的多態。
(1)類之間的繼承關係滿足賦值兼容規則。
(2)改寫同名虛函數
(3)根據賦值兼容性規則使用指針
滿足錢聯條件不一定產生動態編譯,必須同時滿足第3條才能保證實現動態編譯。第3友分爲兩種情況:第1中是已經演示過的按賦值兼容性規則使用基類指針(或引用)訪問虛函數;第2種是把指針(或引用)作爲函數參數,即這個函數不一定是類的成員函數,可以是普通函數,而且可以重載。
8.2.3構造函數和析構函數調用虛函數
在構造函數和析構函數中調用虛函數採用靜態聯編,
在建立類C的對象c時,它所包含的基類對象在派生類中定義的成員建立之前被建立。在對象撤銷時,該對象所包含的在派生類中定義的成員要先於基類對象之前撤銷。
目前推存的C++標準不支持虛構函數。有於析構函數不允許有參數,因此一個類只能有一個虛析構函數。虛析構函數使用vitual說明。
Delete運算符合析構函數一起工作(new和構造函數一起工作),當使用delete刪除一個對象時,delete隱含着對析構函數的一次調用,如果析構函數爲虛函數,則這個調用採用動態聯編。
8.2.4純虛函數與抽象
Virtual 函數類型 函數名(參數列表)=0;
一個類可以說明多個純虛函數,包含有純虛函數的類稱爲抽象類。
如果通過同一個基類派生一系列的類,則將這些類總稱爲類族。
抽象至少含有一個虛函數,而且至少有一個虛函數是純虛函數,
8.3 多重繼承於虛函數
8.4類成員函數的指針與多態
在派生類中,當一個指向某基類成員的指針向一個虛函數,並且通過指向對象的基類指針(或引用)訪問這個虛函數時,仍發生多態性。
第九章
運算符重載及流類庫
9.1 運算符重載
9.1.1 重載對象的賦值運算符
這個成員函數必須使用引用參數,“賦值函數”使用符號“operator=”表示,C++的關鍵字“operator”和運算符一起使用就表示一個運算符函數,
9.1.2運算符重載的實質
爲用戶定義的類型重載運算符都要求能夠訪問這個類型的私有成員,所以只有兩條路可走:要麼將運算符重載爲這個類型的成員函數,要麼將運算符重載爲這個類型的友元。
C++的運算符大部分都可以重載,不能重載的只有.、∷、*和?:。前面3個是因爲在C++中有特定的含義,不準從重載避免不必要的麻煩;“?:”則是因爲不值得重載。另外,“sizeof”和“#”不是運算符,因而不能重載,而=、()、[]、->這4個運算符只能用類運算符來重載。
9.1.3《、》和++運算符重載實例
9.1.4 類運算符和友元運算符的區別
如果對象作爲重載運算符函數的參數,則可使用構造函數將常量轉換成該類型的對象。如果使用引用作爲參數,因爲這些常量不能作爲對象名使用,所以編譯系統就要報錯。
成員運算比友元運算符少一個參數,這是因爲成員函數具有this指針。Complex&a是形參表,a是類complex的引用對象,所以使用對象名。
9.1.5下標運算符“[]”的重載
9.2流類庫
9.2.1流類庫的基礎類
在C++中,輸入輸出是通過流來完成的。C++的輸出操作將一個對象的狀態轉換成一個字符序列,輸出到某個地方。
接收輸出數據的地方叫做目標,把輸入數據來自的地方叫源。
這個執行輸入和輸出操作的體系就叫做流類,提供這個流類實現的系統庫就叫做流類庫。
這些基礎類在頭文件中說明。
在C++中,如果在多條件繼承路徑上有一個匯合處,則稱爲這個匯合處的基類爲公共基類(ios類符合條件)。
C++的流類庫預定義了4個流它們是cin、cout、cerr、和clog。事實上,可以講cin視爲類istream的一個對象,而將cout視爲類otream的對象。
9.2.2默認輸入輸出格式控制
9.2.3 使用ios_base類
1ios_base類簡介
這些常量提供成員函數ios_base、∷setf(fmtflage)來設置類的格式。格式標誌存放在每個流的一個長整形成員中,每個標誌佔1位,在ios_base類中定義。
2直接使用格式控制
3使用成員函數
9.3文件流
9.3.1 使用文件流
流類具有支持文件的能力,在建立和使用文件時,就像使用cin和cout一樣方便。
假如建立一個類似cout以樣使用myFile只要myFile也是ofstream類型對象,就可像使用cout一樣,使用myFile將指定內容希爾文件。
(1)打開一個相應的文件流。
(2)把這個劉和相應的文件關聯起來。
(3)操作問了流
9.3.2幾個典型流成員函數
1輸出的open函數
2輸入流類的open函數
3close成員函數
4錯誤處理函數
9.3.3文件存取綜合實例
1頭文件studebt.H
2源文件student .cpp