常對象
常對象是指該對象在其生命周期内,其所有的資料成員的值都不能被改變;定義對象時加上關鍵字const,該對象就是常對象,其一般形式如下:
類名 const 對象名[(實參類别)];
或者
const 類名 對象名[(實參類别)];
形如:
const CComplex num;
需要特别說明的是:
1. 常對象隻能調用常成員函數,不能調用普通成員函數 (除了隐式調用析構函數和構造函數),常成員函數是常對象的唯一對外接口;
2. 現在編譯系統隻檢查函數的聲明,隻要發現調用了常對象的成員函數,而且該函數未被聲明為const,編譯階段就報錯;
3. 常對象在被定義時需要被初始化;
類設計源碼:
class CComplex
{
public:
//普通構造函數
CComplex(int nReal, int nImag):m_nReal(nReal),m_nImag(nImag)
{
cout << "common constructor function" << endl;
}
int GetRealNum()
{
return m_nReal;
}
private:
int m_nReal;
int m_nImag;
};
//常對象
const CComplex num1(1,1);
//error:不能将“this”指針從“const CComplex”轉換為“CComplex &”
int nReal = num1.GetRealNum();
編譯錯誤的原因是,目前該函數還是普通函數,它可能會修改成員變量;為了常對象能調用GetRealNum函數,應該将該函數設計成常成員函數;
形如
int GetRealNum() const;
常資料成員
如果我們希望在建立對象後,該對象的某個資料成員就保持不變,我們可以将這個資料成員設定為常資料成員;常資料成員隻能通過構造函數初始化清單進行初始化,其他形式的函數均不能進行資料的指派;
常成員函數
若将成員函數設定為常成員函數,則隻能引用本類中的資料成員,而不能修改它;常成員函數可以引用const資料成員,也可以引用非const的資料成員;常成員函數的一般形式為:
類型名 函數名(形參清單) const
這裡的const關鍵字是函數類型的一部分,在函數聲明和函數定義時都要帶const關鍵字,否則被編譯器認為是不同的兩個函數,但是在函數調用的時候不必帶const;
形如:
//聲明和定義一起實作
int GetRealNum() const
{
return m_nReal;
}
函數API設計總結
(1) 若我們定義了一個常對象,則指向這個常對象的指針變量或者對象引用也需要是const類型的;一般形式如下:
const 類型名* 指針變量名;
const 類型名& 引用名;
(2)常對象的唯一對外接口是常成員函數;
(3)為了節約時間開銷和時間開銷,一般将函數形參定義為指針或者引用類型;
(4)若不希望傳入的實參對象被修改,應該将形參定義指向常對象的指針變量或者引用;
根據以上幾點知識,我們進行類設計時,最好遵循以下兩點結論:
1.将不涉及資料成員修改的函數定義為常成員函數;
形如:
int GetRealNum() const
2.當發生函數調用時,希望傳入的實參對象不被修改,應當将形參定義為const類型的指針或者引用;這個實參可以是const類型的,也可以是非const類型的,函數接口相容性更加,形如:
static void TransByPointer(const CComplex* obj)
{
cout << "TransByPointer
" << endl;
}
static void TransByRefence(const CComplex& obj)
{
cout << "TransByRefence
" << endl;
}
下面給出const相關知識的具體調用說明:
資料成員 | 非const的普通成員函數 | const成員函數 |
---|---|---|
非const的普通資料成員 | 可以引用,也可以改變值 | 可以引用,但不可以改變值 |
const資料成員 | 可以引用,但不可以改變值 | 可以引用,但不可以改變值 |
const對象 | 不允許 | 可以引用,但不可以改變值 |