關鍵字class開頭,後跟類的名稱。類的主體被包在花括號中。類定義後必須跟著一個分號或列表。
class Line{
private:
double length;
public:
void setLength(double len);
double getLength();
};
聲明類的對象,就像聲明基本類型的變量一樣。注意區分普通變量和引用變量的區別。
Line line1 ;//聲明普通變量
Line* line2 = new Line;//聲明指針變量
delete line2;
普通變量的內存占用由編譯器去管理 。指針變量的內存占用由開發人員手動管理
普通變量和指針變量訪問數據成員的方式不一樣,都只能訪問公共成員變量和函數——用public 聲明。
Line line1 ;
Line* line2 = new Line;
line1.setLength(10.0);
line2->setLength(11.1);
cout<<"line1 "<getLength()<
普通變量的公共成員用運算符(.)訪問。指針變量的公共成員用運算符(->)訪問。
類成員函數
類的成員函數是指那些把定義和原型寫在類定義內部的函數,就像類定義中的其他變量一樣。類成員函數是類的一個成員,它可以操作類的任意對象,可以訪問對象中的所有成員。
成員函數可以定義在類定義內部,或者單獨使用范圍解析運算符(::)來定義。在類定義中定義的成員函數把函數聲明為內聯的,即便沒有使用 inline 標識符。
class Line{
private:
double length;
public:
void setLength(double len);
double getLength();
void print(){//定義在類內部,也就是內聯函數
cout<<"line's length is "<
內聯函數
內聯函數從源代碼層看,有函數的結構,而在編譯後,卻不具備函數的性質。內聯函數不是在調用時發生控制轉移,而是在編譯時將函數體嵌入在每一個調用處。編譯時,類似宏替換,使用函數體替換調用處的函數名。一般在代碼中用inline修飾,但是能否形成內聯函數,需要看編譯器對該函數定義的具體處理。
//用關鍵字inline定義內聯函數
inline void printLine(Line line){
cout<<"line's length is "<
構造函數與析構函數
構造函數是一種特殊的成員函數,會在每次創建類的新對象時執行。析構函數函數則在每次刪除所創建的對象時執行。
特征
構造函數
析構函數
名稱
類名
~類名
返回類型
無
無
參數
可以有參數
不可以有參數
用途
為某些成員變量設置初始值
在跳出程序前釋放資源
其他
能夠重載
不能夠重載
關於函數重載將在後後續博文中介紹
class Line{
private:
double length;
public:
void setLength(double len);
double getLength();
void print(){
cout<<"line's length is "<
眼尖的伙伴也許發現了這裡調用了三次析構函數。分析第三行到第6行的輸出,調用函數
printLine
首先會調用拷貝構造函數給形參復初始化,再執行printLine
的函數體,最後釋放形參暫用的資源。
友元函數
友元可以是一個函數,該函數被稱為友元函數。友元也可以是一個類,該類被成為友元類。在這種情況下,整個類及其所有成員都是友元。 友元函數是定義在類的外部卻可以訪問類的內部成員(private 和protected)。友元函數的原型在類的內部定義,但是不是類的成員函數。通常用關鍵字 friend 修飾聲明的函數為一個類的友元。
class Line{
private:
double length;
public:
void setLength(double len);
double getLength();
void print(){
cout<<"line's length is "<
對比友元函數、內聯函數、成員函數的定義。成員函數和友元函數可以訪問類的內部成員。但是友元函數必須基於類的對象訪問類的內部成員。友元函數和內聯函數不需要范圍解析運算符,因為他們不屬於類的成員函數。
this指針
每一個對象都能通過 this 指針來訪問自己的地址。this 指針是所有成員函數的隱含參數。因此,在成員函數內部,它可以用來指向調用對象。
友元函數沒有 this 指針,因為友元不是類的成員。只有成員函數才有 this 指針。
Line Line::changeLine(double length){
this->length = length;//第一個length是類的成員變量,第二個length是形參
cout<<"line's length is "<length<setLength(11.1);
printLine(line1);
cout<<"line1 "<getLength()<changeLine(23);
cout<<"line3 "<
object is created 12
object is created 0
copy Line
line's length is 10
called by printLine
object is deleted
line1 10
line2 11.1
line's length is 23
called by changeLine
copy Line
line3 23
object is deleted
object is deleted
object is deleted
分析第9~13行的輸出,
return *this;
會再次生成一個line對象。因此後續會依次釋放line1、line2、line3 的資源。
靜態成員
在類的定義中,用static 關鍵字把類的成員定義為靜態的。無論創建多少個對象,靜態成員都只有一個副本。訪問靜態成員的方式:classname :: staticmember。靜態成員可以是成員變量也可以是成員函數。
//完整版Line類
#include
using namespace std;
class Line{
private:
double length;
static int objcount;//聲明靜態成員變量
public:
void setLength(double len);
double getLength();
void print(){
cout<<"line's length is "<length<setLength(11.1);
printLine(line1);
cout<<"line1 "<getLength()<changeLine(23);
cout<<"line3 "<
object is created 12
1 objects left
object is created 0
2 objects left
copy Line
3 objects left
line's length is 10
called by printLine
object is deleted
2 objects left
line1 10
line2 11.1
line's length is 23
called by changeLine
copy Line
3 objects left
line3 23
obj count is 3
object is deleted
2 objects left
object is deleted
1 objects left
object is deleted
0 objects left
最後,自行分析程序運行結果。