- const關鍵字
1、const修飾普通變量和指針 const修飾變量,一般有兩種寫法:
const TYPE value;
TYPE const value;
兩種寫法在本質上是一樣的。含義是:const修飾的類型為TYPE的變量value是不可變的。對于一個非指針的類型TYPE,無論怎麼寫,都是一個含義,即value值不可變。 例如:
const int nValue; //nValue是const
int const nValue; //nValue是const
但是對于指針類型的TYPE,不同的寫法會有不同情況:
指針本身是常量不可變
(char*) const pContent;
指針所指向的内容是常量不可變
const (char) *pContent;
(char) const *pContent;
兩者都不可變
const char* const pContent;
識别const到底是修飾指針還是指針所指的對象,還有一個較為簡便的方法,也就是沿着*号劃一條線:
如果const位于*的左側,則const就是用來修飾指針所指向的變量,即指針指向為常量;
如果const位于*的右側,const就是修飾指針本身,即指針本身是常量。
2、const修飾函數參數
const修飾函數參數是它最廣泛的一種用途,它表示在函數體中不能修改參數的值(包括參數本身的值或者參數其中包含的值):
void function(const int Var); //傳遞過來的參數在函數内不可以改變(無意義,該函數以傳值的方式調用)
void function(const char* Var); //參數指針所指内容為常量不可變
void function(char* const Var); //參數指針本身為常量不可變(也無意義,var本身也是通過傳值的形式指派的)
void function(const Class& Var); //引用參數在函數内不可以改變
參數const通常用于參數為指針或引用的情況,若輸入參數采用“值傳遞”方式,由于函數将自動産生臨時變量用于複制該參數,該參數本就不需要保護,是以不用const修飾。
3、const修飾類對象/對象指針/對象引用
const修飾類對象表示該對象為常量對象,其中的任何成員都不能被修改。對于對象指針和對象引用也是一樣。
const修飾的對象,該對象的任何非const成員函數都不能被調用,因為任何非const成員函數會有修改成員變量的企圖。
例如:
class AAA
{
void func1();
void func2() const;
}
const AAA aObj;
aObj.func1(); 錯誤
aObj.func2(); 正确
const AAA* aObj = new AAA();
aObj->func1(); 錯誤
aObj->func2(); 正确
4、const修飾資料成員
const資料成員隻在某個對象生存期内是常量,而對于整個類而言卻是可變的。因為類可以建立多個對象,不同的對象其const資料成員的值可以不同。是以不能在類聲明中初始化const資料成員,因為類的對象未被建立時,編譯器不知道const 資料成員的值是什麼,例如:
class A
{
const int size = 100; //錯誤
int array[size]; //錯誤,未知的size
}
const資料成員的初始化隻能在類的構造函數的初始化清單中進行。要想建立在整個類中都恒定的常量,可以用類中的枚舉常量來實作,例如:
class A
{
…
enum {size1=100, size2 = 200 };
int array1[size1];
int array2[size2];
…
}
枚舉常量不會占用對象的存儲空間,他們在編譯時被全部求值。但是枚舉常量的隐含資料類型是整數,其最大值有限,且不能表示浮點數。
5、const修飾成員函數
const修飾類的成員函數,用const修飾的成員函數不能改變對象的成員變量。一般把const寫在成員函數的最後:
class A
{
…
void function()const; //常成員函數, 它不改變對象的成員變量. 也不能調用類中任何非const成員函數。
}
對于const類對象/指針/引用,隻能調用類的const成員函數。
- C++關鍵字mutable
(1)mutable的意思是“可變的,易變的”,跟C++中的const是反義詞。
(2)在C++中,mutable也是為了突破const的限制而設定的。被mutable修飾的變量,将永遠處于可變的狀态,即使在一個const函數中
執行個體說明:
#include <iostream>
using namespace std;
class TestMutable
{
public:
TestMutable(){i=0;}
int Output() const
{
return i++; //error C2166: l-value specifies const object
}
private:
int i;
};
int main()
{
TestMutable testMutable;
cout<<testMutable.Output()<<endl;
return 0;
}
顯然i++在const修飾的函數裡是編譯通不過的。
修改代碼:
#include <iostream>
using namespace std;
class TestMutable
{
public:
TestMutable(){i=0;}
int Output() const
{
return i++;
}
private:
mutable int i;
};
int main()
{
TestMutable testMutable;
cout<<testMutable.Output()<<endl;
return 0;
}
在 int i 前面加上 mutable上面就能編譯通過了,馬上可以看出關鍵字mutable的作用了。