C++並不是一種純粹的面向對象的語言,而是一種基於過程和麪向對象的混合型語言。C++面向對象的機制就是爲了解決編寫大程序時遇到的困難。
面向對象的程序設計有4個主要的特點:抽象、封裝、繼承和多態性。C++的類對象體現了抽象和封裝的特徵,在此基礎上再利用繼承和多態性,就成爲真正的面向對象的程序設計。
對象
任何一個對象都應包括兩個要素,屬性和行爲。屬性爲對象的靜態特徵,而行爲是對象的動態特徵。在C++中,每個對象都由數據和函數組成,數據相當於屬性,而函數相當於行爲。
封裝與信息隱蔽
對一個對象進行封裝處理,把內部實現和外部行爲分隔開,只留下少量接口與外界聯繫,C++類對象中的函數名就是對象的對外接口,外界可以通過函數名來調用函數實現功能。這樣可以大大降低人們操作對象的複雜程度。
利用“封裝性”將對象中的某些部分對外隱蔽,這種做法稱爲信息隱蔽,信息隱蔽有利於數據安全,防止無關的人瞭解和修改。
抽象
抽象的作用是表示同一類事物的本質。類是對象的抽象,對象是類的具體實例,即類的具體表現形式。
繼承與重用
舉個例子,如果已經跟人介紹了什麼是“馬”,那麼再跟人介紹“白馬”的時候只需說明“白馬”是“白色的馬”,省去了重新介紹馬的過程。“白馬”繼承了“馬”的特徵,另外又增加了新的特徵。“馬”是父類(或稱基類),“白馬”是從“馬”派生來的,稱爲子類(或派生類)。
C++提供了繼承機制,採用繼承的方法可以很方便地利用已有類建立一個新的類,這就可以重用軟件中的內容,這就是常說的“軟件重用”。
多態性
由繼承而產生的不同的派生類,其對象對同一消息會作出不同的響應。多態性是面向對象程序設計的一個重要特徵,能增加程序的靈活性。
類的聲明
class student
{
public:
void display()
{
cout<<"name:"<<stu[i].name<<endl;
cout<<"rank:"<<stu[i].rank<<endl;
cout<<"average:"<<stu[i].score<<endl;
}
private:
int rank;
char name[5];
double score;
};
需要注意的是,類的定義中系統默認爲private,而結構體類型定義中默認爲public。
private和public稱爲成員訪問限定符。用它們來聲明各成員的訪問屬性。private聲明的成員只能被類中的成員函數或友元類調用。此外還有一種成員訪問限定符protected,它聲明的成員只能被成員函數或派生類的成員函數調用。
對象的定義方式跟定義結構體類型變量的方式類似。
成員函數
1)類外定義成員函數
class student
{
public:
void display();
private:
int rank;
char name[5];
double score;
};
void student::display() /*“::”是作用域限定符*/
{
cout<<"name:"<<stu[i].name<<endl;
cout<<"rank:"<<stu[i].rank<<endl;
cout<<"average:"<<stu[i].score<<endl;
}
2)內置成員函數
如果在類體中定義成員函數,且函數不包括複雜的控制結構,C++系統會自動對它們作內置函數處理。這樣可以大大減少調用成員函數的時間開銷。
如果要在類外定義內置函數,只需在前面加上關鍵字inline。
3)成員函數的存儲方式
一個對象所佔的內存空間大小隻取決於該對象中數據成員所佔空間,而與成員函數無關。函數的目標代碼是存儲在對象空間之外的。
雖然成員函數並沒有存放在對象的存儲空間內,但從邏輯的角度,成員函數和數據一起封裝在一個對象中,只允許本對象的成員函數訪問同一對象的數據。
這裏就有一個問題,不同的對象調用同一段函數代碼,函數代碼是怎麼對不同對象中的數據進行操作的?
答:C++設立了this指針,調用某對象的成員函數時,this指針就指向該對象,成員函數訪問的就是該對象的數據成員。
對象成員的引用與結構體類型變量的引用類似。
類聲明和成員函數的定義分離
一個C++程序是由3部分組成的:(1)類聲明頭文件(後綴爲.h);(2)類實現文件(後綴爲.cpp),它包括成員函數的定義;(3)類使用文件(後綴爲.cpp),即主文件。
在系統提供的頭文件中只包括對成員函數的聲明,而不包括成員函數的定義。只有把成員函數的定義單獨放在另一個文件中,單獨編譯,才能做到不重複編譯。
在實際工作中,並不是將一個類聲明做成一個頭文件,而是將若干個常用的功能相近的類聲明集中在一起,形成類庫。類庫包括兩個組成部分:(1)包括類聲明的頭文件;(2)經過編譯的成員函數的定義,它是目標文件.obj。