常資料成員的使用及初始化
常的概念我們在學C語言時候就有了解,關鍵字是const ,所謂的“常”,或者說被“常”修飾的變量,是不可以被改變的,比如用const修飾的一個變量就成了常變量,這個值不可被更改。
那麼C++中,一樣有常的概念,額外不同的是,const除了可以修飾一般的變數為常變數之外,還可用來修飾某個對象,變成常對象。以及可以修飾類別的資料成員和成員函數,分別叫做類別的常資料成員和常成員函數。
下面,我們依序對常資料成員、常成員函數、常物件展開講解。
1. 常資料成員:
對於常資料成員的用法,與我們在C語言的用法一樣,只不過這部分資料出現在類別裡,使用的格式如下:
資料型別const 資料成員名;
或
const 資料型別資料成員名;
被const修飾的成員必須進行初始化,並且不能被更改,而初始化的方式則是在類別的建構子的初始化列表裡進行的。
另外,有一個特殊情況,如果成員是static類型,也就是靜態常資料成員,因為是靜態的屬性,初始化則需要在類別外進行初始化。下面我們把剛才講的情況放到程式碼裡來說明:
#include<iostream>usingnamespacestd;classClock{private:constinth;//修飾h為常類型成員constintm;//修飾m為常類型成員intconsts;//和上面兩種用法都可以staticconstintx;public:Clock(inta, intb,intc):h(a),m(b),s(c){cout<<Constrctor!Called<<endl;}intShowTime(){cout<<h<<:<<m<<:<< s<<endl;return0;}intGetX(){cout<<x<<endl;return0;}};constintClock::x=99;intmain(){ClockA(12,10,30);A.ShowTime() ;A.GetX();return0;}
運行演示結果:
大家注意看類別中的四個常數資料成員,其中X為static類型,因其靜態化的特殊屬性則需要在類別外初始化,即便X為私有類型!
2. 常對象:
C++中可以把一個物件宣告為const型,也就是常物件。這樣宣告之後,這個物件在整個生命週期中就不可以再被更改,所以在定義的時候要由建構函式進行初始化,定義格式如下:
類型const 物件名;
或
const 類型物件名稱;
要注意的是,常物件不可以存取類別中的非常成員函數,只能存取常成員函數(後面第三部分)。下面我們來看例子:
#include<iostream>usingnamespacestd;classClock{private:constinth;//修飾h為常數成員constintm;//修飾m為常類型成員intconsts;//和上面兩種用法都可以intx;public:Clock(inta, intb,intc):h(a),m(b),s(c){x=99;cout<<Constrctor!Called<<endl;}intShowTime(){cout<<h<<:<<m< <:<<s<<endl;return0;}intGetX()const{//x=99;cout<<x<<endl;return0;}};intmain(){constClockA(12,10,30);constClockB (14,20,50);//A=B;//A.ShowTime();A.GetX();return0;}
注意看程式碼中39,40行的語句,正常編譯將報錯,原因是A為常物件不可以被賦值,以及ShowTime函數為非常成員函數。而41行的程式碼則可以執行,效果如下:
3. 常成員函數:
類似的,一個類別中的成員函數被const修飾後,就變成了常成員函數,常成員函數的定義如下:
傳回類型函數名(形參表列) const;
需要注意:
(1)常成員函數的定義和宣告部分都要包含const;
(2)常成員函數只能呼叫常成員函數,而不能呼叫非常成員函數,存取但不可以更改非常成員變數。
例如以下程式碼:
#include<iostream>usingnamespacestd;classClock{private:constinth;//修飾h為常數成員constintm;//修飾m為常類型成員intconsts;//和上面兩種用法都可以intx;public:Clock(inta, intb,intc):h(a),m(b),s(c){x=99;cout<<Constrctor!Called<<endl;}intShowTime(){cout<<h<<:<<m< <:<<s<<endl;return0;}intGetX()const{//x=99;cout<<x<<endl;return0;}};intmain(){constClockA(12,10,30);A .GetX();return0;}
注意第29、30行程式碼,如果使用29行程式碼則會編譯報錯,實際運作效果如下:
C++中常概念的建立,明確了程式中各物件的變與不變的邊界,也強化了C++程式的安全性與可控制性。
請大家自行上機實驗。