[轉]C++類成員修飾const和mutable

const:常量,不變的ios

mutable:易變的函數

從意思上理解,可見const和mutable是一對反義詞,它們都是C++的關鍵字。this

 

const成員函數不能修改調用它的對象。類的成員函數能夠被聲明爲const,這將使得函數的隱式參數this將被做爲const類型的指針。這也就意味着一個const成員函數不能修改調用它的對象。並且,const對象不能調用非const成員函數。然而,const對象和非const對象均可以調用const成員函數。spa

要將一個成員函數聲明爲const,可使用下面的形式:.net

 C++ Code 
1
2
3
4
5
6
 
class  X
{
    
int  some_var;
public :
    
int  f1()  const ;     //const成員函數
};

能夠看到,關鍵字const被放在函數聲明以後。將一個成員函數聲明爲const的目的是防止函數修改調用它的對象。例以下面的代碼:指針

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 
#include  <iostream>
using   namespace  std;

//說明const函數的用法,這個程序不能經過編譯
class  Demo
{
    
int  i;
public :
    
int  get()  const
    {
        
return  i;         //正確
    }
    
void  seti( int  x)  const
    {
        i = x;          
//錯誤!
    };
};

void  main()
{
    Demo ob;
    ob.seti(
1900 );
    cout << ob.get() << endl;
}

上面的這個程序不能經過編譯,由於函數seti()被聲明爲const成員函數,這意味着在函數中不能修改調用函數的對象。可是因爲seti()試圖修改爲員變量i,因此程序會產生錯誤,而在函數geti()中並不修改爲員變量i,因此這個函數是正確的。orm

有時你可能想在const函數中修改類的某些成員,但又不想讓函數修改類的其它成員,那麼能夠經過關鍵字mutable來實現這種功能。mutable將覆蓋const屬性。也就是說,在const成員函數中能夠修改mutable成員,例如:對象

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 
#include  <iostream>
using   namespace  std;

//能夠經過編譯,運行正確
class  Demo
{
    
mutable  int  i;
public :
    
int  get()  const
    {
        
return  i;                 //正確
    }

    
void  seti( int  x)  const
    {
        i = x;                  
//錯誤!Maybe
    };
};

void  main()
{
    Demo ob;
    ob.seti(
1900 );
    cout << ob.get() << endl;
}

//運行結果
1900

在上面的程序中,類的成員變量i被定義爲mutable,因此在函數seti()中能夠修改它的值。blog

 

const成員變量的初始化 ci

在構造函數中對成員變量進行初始化是很廣泛的初始化方法,然而,這種方法並非適用於全部狀況,例如:若是在類的定義中使用了const來聲明成員變量,那麼在類的構造函數中將不能對這些成員變量賦初始值,由於const變量必須在構造函數調用以前被初始化,在使用"引用類型的成員"以及"沒有默認構造函數的成員"時存在着一樣的問題,由於這些成員必須首先被初始化。爲了解決這個問題,在C++中定義了一種成員初始化語法,能夠在建立對象時爲類的成員指定初始值。

成員初始化語法 相似於 調用基類構造函數的語法,它的通用形式以下所示:

 C++ Code 
1
2
3
4
5
6
7
 
constructor(arg_list)
    : member(initlalizer)
    , member(initlalizer)
    , member(initlalizer)
{
     //構造函數體
}

在構造函數的後面指定你想要初始化的成員,同時用冒號將構造函數的名字和參數列表分開。也能夠將基類構造函數的調用和成員的初始化放在同一參數列表中。

相關文章
相關標籤/搜索