類的主要思想就是資料抽象和封裝。
一、定義乙個類
我們首先來看乙個例子:
class test // 類名
private: //訪問說明符, private之後的成員只能被類的成員函式訪問,但是不能被使用該類的**訪問
int m_a; //類的成員變數
};
通過上面的例子我們就可以知道類是如何定義的。
我們除了可以通過class 來定義乙個類,還可以通過struct來定義乙個類。struct 在c語言中是用來定義乙個結構體的。
struct和class定義的類的區別:
struct:用struct定義的類,在第乙個訪問說明符出現之前的成員都是public的
class:用class定義的類,在第乙個訪問說明符出現之前的成員都是private的
其他都是一樣的!
類的組成
類由類名,訪問說明符,成員變數和成員函式構成,還是看第乙個例子,我們可以很清晰的知道類的組成。m_a是類的成員變數,print()函式是類的成員函式,類名是test。
二、建構函式
建構函式也是類的成員函式,建構函式的名字和類名相同,但是沒有返回值,其他的都是和普通的函式一樣的,所以建構函式是可以過載的。
我們也來看乙個有建構函式的例子:
class test
;
類裡面的test()函式就是建構函式,這兩個建構函式的形參不一樣所以是過載函式。如果對過載函式有什麼不理解的可以去看一下我的這篇部落格。c++複習之路六——函式, 這個裡面有對函式過載的介紹。
建構函式的作用
建構函式主要用來初始化類物件的資料成員。
1、預設建構函式
如果我們沒有顯示的定義乙個建構函式,編譯器會為我們隱式的定義乙個建構函式用來對類的物件進行初始化工作。相反如果我們顯示的定義了乙個建構函式,編譯器就不會給我們定義預設的建構函式。
建議:我們在定義乙個類的時候最好定義乙個建構函式,因為我們不能確定編譯器給我們生成的預設建構函式是否符合我們的需求,也許預設建構函式會執行錯誤的操作。
2、拷貝建構函式
拷貝建構函式也是建構函式的一種,但是也是比較難理解的一種。所以使用c++的朋友一定要注意拷貝建構函式的使用。
拷貝建構函式的宣告,以上面的test類為例。
test(const test& p); // 拷貝建構函式
【注意】:拷貝建構函式的第乙個引數必須是類本身的引用型別。
拷貝構造函式呼叫的幾種場景。
①乙個類的物件使用等號初始化另乙個類的物件的時候。(拷貝初始化)
test t1(1, 2);
test t2 = t1;
t1是乙個test類的物件,第二條語句定義了另乙個test物件t2並且用t1初始化這個物件,這個時候就呼叫了拷貝建構函式。(完整的**會在最後貼出來,希望能夠幫助讀者更好的理解)
②乙個類物件使用括號來初始化另乙個類物件的時候。(直接初始化)
test t1(1, 2);
test t3(t1);
第二條語句是用t1物件初始化t3物件,這個時候也會呼叫拷貝建構函式。
③將乙個類的物件作為實參傳遞給乙個非引用型別的形參。
void diaoyong(test obj) //引數為乙個非引用型別的test類的形參
test t1(1, 2);//定義乙個test類的物件。
diaoyong(t1);//將實參傳遞給形參。
在我們呼叫diaoyong()函式的時候,形參將會拷貝實參的值,這個時候就會呼叫拷貝建構函式。
④從乙個返回型別為非引用型別的函式返回乙個物件
test fanhui()
上面這個例子在fanhui()函式中定義了乙個test t4,然後返回這個物件,在
返回的過程中會產生乙個匿名物件,並且用這個t4物件來初始化這個匿名物件。所以這個時候就會呼叫拷貝建構函式。然後函式結束就會把t4這個物件析構掉!
三、析構函式
析構函式的作用:
釋放物件使用的資源,並銷毀物件的非static成員。
析構函式是類的乙個成員函式,名字右波浪號(~)和類名構成。
~test();//析構函式的宣告
【注意】:析構函式沒有返回值,也不接受引數,所以析構函式不能夠過載。
析構函式是編譯器自動呼叫的,在以下幾種情況會自動呼叫:
1、變數在離開其作用域時被銷毀。
2、當乙個物件被銷毀時,其成員被銷毀。
3、容器(無論是標準庫容器還是陣列)被銷毀時,其元素被銷毀。
4、對於動態分配的物件,當對指向它的指標應用delete運算子時被銷毀。
5、對於臨時物件,當建立它的完整表示式結束時被銷毀。
四、類物件的定義
我們就用之前的test 類來說明。
class test
;
如果我們想定義乙個無參的物件,我們可以這樣定義:
test t1;//定義了乙個無參的物件
也許有人會這樣寫,test t1(); 注意這樣寫是不正確的,雖然我們在無參建構函式宣告的時候寫了(), 但是如果定義的時候也加上了(),編譯器會報這樣的錯誤:「test t1(void)」: 未呼叫原型函式(是否是有意用變數定義的?)。
定義帶兩個引數的物件。
test t1(1, 2);//定義了帶兩個引數的物件
這樣我們的建構函式會用兩個引數去初始化test類裡面的成員變數。
當然我們還可以這樣來定義乙個物件
test t1(1, 2);
test t2 = t1;
這樣是用t1物件初始化t2物件,這個時候就會呼叫拷貝建構函式。
/*
*這斷**展示了何時呼叫建構函式,以及建構函式的過載
*還展示了四種呼叫拷貝建構函式的情形
*還有何時呼叫析構函式。
*如果想要更清楚的了解何時呼叫建構函式,以及析構函式,可以加上斷點,不斷的除錯
*相信經過除錯都會一清二楚的。
*/#include using namespace std;
class test
;test::test()
test::test(int a, int b)
test::~test()
test::test(const test& p)
void test::printt()
void diaoyong(test obj)
//這個函式返回的時候回生成乙個臨時變數(匿名物件),用t4初始化這個匿名物件會呼叫拷貝
//建構函式
test fanhui()
void fun() //這個函式的作用就是能夠完整的展示物件的宣告週期。(主要是用來看析構函式是否被呼叫)
int main()
C 複習之路 1
複習書目 c primer plus 編譯器 vs2013 第4章 復合型別 4.1陣列 陣列宣告應指出以下三點 1 儲存在每個元素中的值得型別 2 陣列名 3 陣列中的元素數。short months 12 元素型別為short型,陣列名為months,陣列中元素數為12 c 陣列從0開始編號的!...
C 複習之路四 表示式
一 表示式的概念 表示式是由乙個或多個運算物件組成,運算物件之間可以通過運算子連線起來。二 復合表示式 復合表示式是指含有兩個或者多個運算子的表示式。注意 復合表示式進行運算的時候要注意運算子的優先順序。三 算數運算子的優先順序表 算數運算子 左結合律 運算子功能用法 一元正號 一元負號 expr ...
C 複習之路十一 類的繼承
一 複習三種訪問控制符 public 修飾的成員變數或者方法,可以在類的外部或者類的內部使用 private 修飾的成員變數或者方法,只能在類的內部使用,外部不能使用 protected 修飾的成員變數或者方法,只能在類的內部或者子類內部使用,不能在類的外部使用 這三種訪問控制符可以修飾類的成員屬性...