1. 程式人生 > >C++中const關鍵字修飾

C++中const關鍵字修飾

C++中const使用的地方非常多,修飾包括:全域性變數、函式、函式引數等等,這篇文章主要是總結一下const各種使用的規則以及需要注意事項。

const名叫常量限定符,用來限定特定變數,以通知編譯器該變數是不可修改的。習慣性的使用const,可以避免在函式中對某些不應修改的變數造成可能的改動。

C++中const的主要用法大致上可以分為以下幾類:

  • 修飾基本資料型別
  • 應用到函式中
  • 在類中用法
  • const修飾類物件,定義常量物件

1.const修飾基本資料型別

主要是修飾值變數、reference、pointer

1.1修飾一般常量或則陣列

比如:

const int a = 10;
const int arr[3]={1,2,3}; 

對於類似這些基本資料型別,修飾符const可以用在型別說明符前,也可以用在型別說明符後,其結果是一樣的。在使用這些常量的時候,只要不改變這些常量的值便好。

1.2const修飾指標變數*及引用變數&

const修飾指標(*)

這裡有一些實際的示例:

int x= 100;
const int* a1 = &x;//[1]
int const * a2 = &x;//[2]
int* const a3 = &x;//[3]
const
int* const a = &x;//[4]

《Effective c++》Item21上的總結非常直觀明瞭。

  • 如果const位於星號*的左側,則const就是用來修飾指標所指向的變數,即指標指向為常量;
  • 如果const位於星號*的右側,const就是修飾指標本身,即指標本身是常量。

根據這條規律,[1]和[2]兩條中,const位於星號的左側,所以const含義是修飾變數a1和a2指標指向的內容是常量,也就是不能做 *a1 = 1或則 *a12 = 1這種類似操作,編譯器會報錯。

[3]為指標本身是常量,而指標所指向的內容不是常量,這種情況下不能對指標本身進行更改操作,如a++是錯誤的.

[4]為指標本身和指向的內容均為常量。

const修飾reference(&)
同樣給出一些示例:

int x =100;
int const &a=x;//[1]
const int &a=x;//[2]
int &const a=x;//[3]這種方式定義是C、C++編譯器未定義,雖然不會報錯,但是該句效果和int &a一樣。   

對於[1]和[2]這兩種定義方式是等價的,此時的引用a的值不能被更新。如:a++ 或則給a賦值這是錯誤的。

2.const應用到函式中

const在函式中的應用主要有三點:

  • 作為引數的const修飾符;
  • 作為函式返回值的const修飾符
  • 作為函式的const修飾符

不管是作為函式引數的const修飾符還是返回值的修飾符,其實際含義都是一樣的。

const修飾函式引數

比如:void fun0(const A* a ); 或則 void fun1(const A& a);
呼叫函式的時候用相應的變數初始化const常量,則在函式體中,按照const修飾的部分進行常量化。

比如const A* a 則不能對傳遞進來的指標指向的內容修改,保護原指標所指向的內容;
比如const A& a則不能對傳遞進來的引用物件的內容修改,保護原引用物件所的內容。

注意:引數const通常用於引數為指標或引用的情況。

const修飾函式返回值

修飾返回值的const,如const A fun2( ); const A* fun3( );
這樣聲明瞭返回值後,const按照"修飾原則"進行修飾,保護函式返回的指標指向的內容或則引用的物件不被修改。

const修飾函式
const作用於函式還有一種情況是,在函式定義的最後面加上const修飾,比如:
A fun4() const;
其意義上是不能修改除了函式區域性變數以外的所在類的任何變數。

3. 類中定義常量(const特殊用法)

我們要想在類中實現常量定義大致上有幾種實現方式

1.使用列舉型別

class test
{
	enum {SIZE1=10, SIZE2=20};//列舉常量
	int array1[SIZE1];
	int array2[SIZE2];
}

2.使用const

不能在類宣告中完成初始化const資料成員。 以下用法編譯器會報錯,因為類物件未被建立時,編譯器不知道SIZE的值是什麼。

// 錯誤例項
class test
{
	const int SIZE = 100;//編譯器報錯,企圖在類宣告中初始化const資料成員
	int array[SIZE];//錯誤,未知SIZE
}

正確使用const用法是:const資料成員的初始化只能在類建構函式的初始化表中進行。

class A
{
	A(int size);//建構函式
	const int SIZE;
};
A::A(int size) : SIZE(size) // 建構函式的初始化表
{

}
//error 賦值的方式是不行的
A::A(int size)
{
     SIZE=size;
}
void main()
{
    A  a(100); // 物件 a 的SIZE值為100
    A  b(200); // 物件 b 的SIZE值為200
}

注意:對const成員變數的初始化,不能在變數宣告的地方,必須在類的建構函式的初始化列表中完成,即使是在建構函式內部賦值也是不行的。

3.使用static const

通過結合靜態變數來實現:

class Year
{
private:
	int y; 
public:
	static int const Inity;
public: 
	Year()
	{
		y=Inity;
	}
};
int const Year::Inity=1997;//靜態變數的賦值方法,注意必須放在類外定義
void main()
{
	cout<<Year.Inity<<endl;//注意呼叫方式,這裡是用類名呼叫的。
}

到這裡就把在類中定義常量的方法都陳列出來了。

4.const定義常量物件,以及常量物件的用法

對於不管是標準庫中的物件或則是我們自定義的物件,如果我們定義的是const物件,那麼對於const物件只能呼叫const修飾的函式,其餘的函式都不能呼叫。

如下例子:

class test
{
public:
    test():x(1)
    {
        y=2;
    }
    ~test()
    {}
    void set(int yy)
    {
        y=yy;
    }
    int getx() const
    {
        return x;
    }
    const int x;
    int y;
};

void main()
{
	const test t;// 定義的一個const物件
	t.set(33);//error,set方法不是const修飾的方法,編譯器會報錯。
	t.getx();
}