天天看點

C++中關鍵字const和mutable的用法總結

  • 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的作用了。

繼續閱讀