C++是一門面向對象的程序語言,關於面向對象和麪向過程,以前看過一篇文章,http://goo.gl/9eD4n,感覺講解的非常好。
第一章類和對象
- 面向對象的基本特徵
- 類是一種複雜的數據類型,將不同類型的數據,與這些數據相關的操作封裝在一起。類是對現實
class { //數據成員和成員函數實現; }obj1, obj2, obj3;//只能定義一次。
客觀世界的抽象,對象是類的一個實體。類具有屬性和行爲兩方面要素。 - 封裝是指將對象的數據與這個數據相關的操作放在一起,形成一個實體——對象。
- 繼承(inheritance)機制可以使某個類(派生類、子類)繼承另一個類(父類、基類)的特徵和能力,加上自己特有的屬性和行爲,實現軟件重用。
- 消息是一個對象向另一個對象發出的服務請求,進行對象之間的通信。
- 多態性(polymorphism)指同一個消息可以根據發送消息對象的不同而採取不同的行爲方式。C++中的多態性包括靜態多態和動態多態。靜態多態在編譯時能決定調用哪個函數,如函數重載,根據參數的不同,執行不同的操作;動態多態是由繼承產生的,相關的但不同的類對象對同一消息會做出不同的響應,多是在程序運行時才能確定操作的對象,常用虛函數(virtual)來實現動態多態性。
- 類和對象
- 類是對象的抽象概括,對象是類的具體實現,由類創建具體的對象。類和對象的定義:
class 類名 { public: //公有,提供與外界的接口。公有成員可以被類作用域內的其他函數使用。 //數據成員和成員函數實現; protected: //保護,類的成員和繼承類可以訪問,類以外的函數不能訪問。 //數據成員和成員函數實現; private: //私有,封裝在類內部,只能被該類的成員、該類的友元函數和友元類訪問。 //數據成員和成員函數實現; };
- 數據成員、成員函數、靜態成員,數據成員就是對象中的數據部分,成員函數就是數據操作部分。
- 類對象的定義:
class myclass { //數據成員和成員函數實現; }; [class] myclass obj1, obj2, obj3;//class 可以省略
class myclass { //數據成員和成員函數實現; }obj1, obj2, obj3;
class { //數據成員和成員函數實現; }obj1, obj2, obj3;//只能定義一次
- 同一個類,不同對象的數據成員是不同的,成員函數是相同的。C++用同一內存空間來存放同種類對象的成員函數代碼,用this指針指明哪個對象的成員函數。
- 類的成員函數
- 內聯(inline)函數指類內定義的成員函數。函數的聲明一般在頭文件中,而頭文件需要多次編譯,所以定義不能放在頭文件中。內聯函數可以放在頭文件中(頭文件外用inline關鍵詞)。內聯函數規模小,調用頻繁,調用時直接將函數代碼嵌入到程序的調用點。
- 在類外定義成員函數,類的聲明,類的定義。作用域運算符::
void Myclass::Myfunction();
- 對象成員引用
- 通過對象名和成員運算符訪問對象中的成員
Myclass.Myobj; Myobj.Myfunction();
- 通過指向對象的指針和指針運算符訪問對象中的成員
Myclass Myobj, *p; p=&Myobj;; p->Myfunction();
- 通過對象的引用變量訪問對象中的成員
Myclass Myobj; Myclass &p=Myobj; //引用變量p p.Myfunction();
- 構造函數和析構函數
- 構造函數在創建對象時初始化數據成員,構析函數在對象生存週期結束時釋放該對象。
- 構造函數
class Myclass { public: //應該是public屬性 Myclass() { //與對象同名 cout<<"調用無參數的構造函數"<<endl; //一個對象在生存週期內只能調用一次 } }Myobj;
class Myclass { public: Myclass(int a, int b=0) { //構析函數可以根據參數定義多個,可以重載構造函數 cout<<"調用有參數的構造函數"<<endl; //構造函數可以帶默認參數 } }Myobj;
- 當主函數運行到結束的花括號時,對象的生存空間結束,析構函數被調用。析構函數的調用順序與構造函數相反。
- 析構函數
class::~Myclass() { //析構 }
- 拷貝函數,默認拷貝構造函數。拷貝函數是特殊的構造函數,用一個已知的對象初始化另一個對象。函數名與類名相同,沒有返回值,只有一個參數,參數爲該類對象的引用。定義格式:
三種情況下,需要拷貝函數初始化構造函數Myclass::Myclass(Myclass &d); //形參是一個對象的引用 Myclass::Myclass(const Myclass &d); //形參是一個const對象的引用
用一個對象創建另一個對象時,如果用戶沒有自己定義拷貝構造函數,編譯系統會自動提供一個默認的拷貝構造函數。默認的拷貝構造函數將一個對象的全部數據成員賦值給另一個對象的數據成員。當類的數據成員中包括動態分配的資源時(char *p),會出現淺拷貝的問題(原對象obj1和拷貝後的對象obj2共用p的對空間,當刪除p時,出現錯誤),這是必須自己定義拷貝函數。Myclass obj1(obj2);//用一個對象初始化另一個對象 function(Myclass obj1); //函數聲明,函數的形參是一個類對象 return obj1; //對象作爲函數的返回值,創建一個臨時對象
- 類和對象的進一步應用
- C++中,動態分配堆空間是使用new和delete分配堆對象時自動調用構造函數和析構函數,用malloc和free不會自動調用,所以儘量使用new和delete。
- 組合類中用抽象的數據類型作爲數據成員。
- 常對象只能訪問常成員函數,常對象中的所有成員數據都不允許改變,只有常成員函數才能訪問這些數據。
Myclass const obj(); const Myclass obj();
- 常數據成員與一般常變量相似,其數值不能改變。常數據成員只能通過構造函數的參數初始化列表對常數據成員進行初始化,不能採用賦初值的方法。
const int v; Myclass::Myclass(int a):v(a){...}; Myclass::Myclass(int a){v=a;};//錯誤
- 常成員函數
常成員函數只能訪問本類中的數據成員(const和非const),不能修改值。只有常成員函數才能操作常量和常對象。int fuction() const;
- 靜態成員
- 聲明爲static的類成員能夠在類的範圍中共享,稱爲數據成員。
- 靜態數據成員
靜態數據成員爲類中所有成員共享,只佔一份內存;靜態數據成員是靜態存儲的,是靜態生存期,在程序開始運行時分配內存,程序結束時釋放內存。static int name; //定義 int Myclass::name=0; //初始化 Myclass::name //靜態數據成員不屬於任何一個對象,可以直接訪問。
- 靜態成員函數
靜態成員函數可以直接訪問靜態數據和靜態成員函數,不能直接訪問非靜態數據和非靜態成員函數,可以通過對象來引用。static int function(); //定義 Myclass::function(); //直接訪問
- 友元函數和友元類
- 類具有封裝和數據隱藏的特性,只有類中的成員函數纔可以訪問protected和private成員。將類外的聲明爲friend後,可以訪問。友元提高了程序的運行效率,但破壞了類的封裝和隱藏性。
- 友元函數
友元函數是類外定義的一個函數,不是類的成員函數。friend int function(); //普通友元函數的聲明 friend int Myclass::function1();//其他類的友元函數聲明爲該類的友元函數
- 友元類
A中的所有成員函數又是B的友元函數,可以訪問B的private成員。友元關係不具有交換性和傳遞性。class B { ..... friend class A; //聲明A爲B的友元類 }
- string類
- char型字符串
動態分配字符串,其長度在運行時確定。Myclass::function(char *s) { len=strlen(s); con=new char[len+1]; strcpy(con,s); }
- string型字符串
string類有很多強大的成員函數。Myclass::fuction(string s) { con=s; }