本文主要介紹const修飾符在C++中的主要用法,下面會從兩個方面進行介紹:類定義中使用const、非類定義中使用const
1. 非類定義中使用const
非類定義中使用const是指:在除了類定義以外的場景中使用const,
1.1 變數
const int a = 1; //定義一個常量,不可以修改
int b = 2; //定義一個普通變數,可以修改
const int &b = a; //定義一個常量參考,不可以通過參考b修改a,底層const
const int *p = &a; //定義一個普通變數,p可以修改,但是不可以通過p修改所指向的物件a,底層const
int * const q = &b; //定義一個常量指標,q不可以修改,但是可以通過q修改所指向的物件b,頂層const
const int * const s = &a; //定義一個常量指標,s不可以修改,同時不可以通過s修改所指向的物件a,靠右的是頂層const,靠左的是底層const
頂層const:變數本身是個常量
底層const:變數所指向的物件是個常量
用于宣告參考的const都是底層const
1.2 函式
int fun1(const int a); //定義一個常量形參
const int fun2(int a); //等同于'int fun1(const int a);'因為函式回傳的是回傳值的副本
const int& fun3(int &a); //回傳常量參考,不會進行物件的拷貝(注意:不要回傳區域物件的參考或者指標)
const int& fun4(int a); //這實際上是一種錯誤的宣告方式,該函式可能會回傳區域物件的參考或者指標
Tips:
- 參考只是一個變數的別名,不是物件,因此參考不會占用存盤空間
- 呼叫一個回傳參考的函式得到左值,其他回傳型別得到右值
2. 類定義中使用const
2.1 類成員
class Test{
public:
Test():a(10){}
void display();
private:
const int a;
};
- 類定義中不能進行初始化,因為在頭檔案中定義只是一個宣告,并沒有分配真正空間,因此變數是不存在的,因此是不能賦值的,
- 在類定義外部,const定義的變數是不能被賦值
問題:
類定義中不能賦值,類定義外部也不能賦值,但是又必須賦值,這可如何是好?
解決方案:
- 在建構式后的引數初始化串列中初始化
- 將const變數同時宣告為 static 型別進行初始化
class Test{
public:
Test():a(10){}
void display();
private:
const int a;
//static const int a;
};
//const int Test::a = 5;
2.2 類成員函式
class Test{
public:
//下面是display函式的兩個多載版本
void display(); //一個普通成員函
void display() const; //一個const成員函式,
private:
const int a;
};
Tips:
成員函式都有一個額外的隱式引數this,this的值是呼叫該函式的物件地址,因此this是一個指標,
普通成員函式的this指標型別是:Test* const this
const成員函式的this指標型別是:const Test* const this
Test t1;
const Test t2;
t1.display(); //呼叫void display()
t2.display(); //呼叫void display() const
因為兩個函式的this指標型別不同,所以display有兩個多載函式,
作用:
為了在函式體內禁止修改物件,可以通過定義const成員函式來實作,
Others:
下圖是截自C++ primer中的片段,請重點關注兩個display函式的回傳值:
display 普通成員函式的回傳值是:普通參考
display const成員函式的回傳值是:常量參考
造成回傳值不同的原因就是:this指標型別不同

3. 參考資料
- C++ primer 第五版-P57、P201、P231、P247
- C++ non-const lvalue reference cannot bind to a temporary
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/56821.html
標籤:C++
上一篇:求助大佬們。
下一篇:結構體與鏈表
