為了提高軟件的復用率與可維護性,現代程序設計方法學中指出,一個軟件系統的框架應該建立在數據之上,而不是操作之上。即在構成軟件系統的每個相對獨立的模塊上定義一組數據和施於這些數據之上的一組操作,並在模塊內部給出這些數據的表示與操作細節,而在模塊外部使用的只是抽象的數據與抽象的操作。
類是一種抽象數據類型ADT(abstract data type),它是一種用戶自己定義的數據類型。它實現了數據抽象和封裝的數據類型,它封裝了復雜數據與操縱復雜數據的程序代碼。
(一)類的定義與聲明
類的一般形式為:
class{
成員列表
};
成員列表是類成員的集合,由具體應用而定;大括號是成員列表的邊界符,與成員列表一起稱為類體。
1)類的數據成員
除了在類中聲明一般的數據成員外,還可以在類中定義自己的局部數據類型,並且使用類型別名來簡化。
class ADT{
struct Point{int x,y;}; //定義結構體
union UData{Point p; long color;}; //定義共用體
enum COLOR{RED,GREEN,BLUE}; //定義枚舉類型
class Nested{ //嵌套類定義
... //成員函數
Point start; //數據成員
UData end;
COLORS color;
};
typedef Point* LPPOINT; //聲明Point的類型別名
... //ADT的成員函數
... //ADT的數據成員
};
在類中定義或聲明的數據類型的作用域是類內部,因此它們不能在類外部使用。
2)類的成員函數
成員函數必須要在成員列表類中聲明,而成員函數的定義即可以在類的內部也可以在類的外部。一般來說在類的內部對成員函數做聲明,在類的外部定義成員函數,是一種比較好的編程習慣。這樣使得類體的長度變短,類結構變得清晰,而且有助於類的接口與實現分離。
class Data{
public:
void set (int d); //成員函數原型聲明
int get(){ //成員函數定義
return data;
}
private:
int data; //數據成員
};
void Data::set(int data) //成員函數的外部定義,使用::類作用域限定符。
{
data=d;
}
void set(int d) //全局普通函數
{}
如果作用域限定符前面不是類名,比如我們在視覺領域常見到的cv::f(),這時::指的是命名空間域限定符。
注意:為了節約空間,C++中每個類的對象所占用的存儲空間只是該對象的數據成員所占用的存儲空間,不包括成員函數存儲空間。成員函數代碼只有公共的一個,調用不同對象的成員函數時都是執行同一段函數空間。
(二)成員訪問控制
類的所有成員都有訪問控制屬性,由下面三種訪問標號說明:public,private,protected,訪問控制屬性用於控制類成員在程序中的可訪問性。
公有成員允許外部類用戶直接通過對象訪問,也允許類內部的成員函數直接訪問。私有成員只有類成員函數才能訪問,它實現了私有成員的隱蔽。保護成員在不考慮繼承的情況下,與私有成員性質一致,但是保護成員可以被派生類的類成員函數訪問。
class{
public:
...
protected:
...
private:
...
};
注意,如果有成員沒有被生聲明上述的訪問控制屬性,則默認其為私有的。
(三)對象的定義與使用
1)定義對象的三種方法:
a)先定義類類型,然后定義類對象。比如說之前已經定義了Point類,下面定義Point類的對象:
Point a,b; //C++特色定義對象
class Point x,y; //兼容C語言特色定義對象
b)定義類類型的同時定義對象。
class Data{ //類名
...
}one, two; //對象列表
c)直接定義對象。
class { //無類名類體
...
}one,two;
其中第一種方法最靈活最普遍。
2)對象的動態建立與釋放
前面介紹的靜態存儲對象占用空間的分配與釋放時間點是固定的。例如,在某函數中定義一個對象,進入函數運行時,為對象分配存儲空間;函數結束運行時,釋放對象占用的空間。
為了提高存儲空間的利用率,可以使用new運算符動態分配對象空間,delete運算符釋放對象空間:
類名* 對象指針變量;
對象指針變量=new 類名;
Point* p; //定義指向Point對象的指針變量
p=new Point; //動態分配Point對象
當不需要使用new建立的動態對象時,必須使用delete運算撤銷,例如:
delete p; //撤銷p所指的對象
注意:new建立的對象不會自動被撤銷,即使程序結束也是如此,必須人為使用delete撤銷。
3)對象成員的引用
訪問對象中的成員有以下三種方法:
a)通過對象名與對象成員引用運算(.)訪問對象成員。
Data A,B;
A.data=10;
A.add(5);
b)通過指向對象的指針和指針成員引用運算(->)訪問對象成員。
Data A,*p,*p1;
p=&A;
p->data=10;
p->add(5)
p1=new Data;
p1->data=10;
delete p;
c)通過對象的引用變量和對象成員引用運算(.)訪問對象成員。
Data A,&r=A; //定義對象的引用變量
r.data=100;
r.fun(1,2,3);