本文主要說明了const關鍵字的作用,包括了用於對數組,指針與類相關的修飾方法,作為筆記總結使用。若有錯誤與不足,歡迎指正。
const關鍵字
用於修飾一個常類型,常類型的變量或對象的值無法被改變,即無法作為左值,因此在定義時必須進行初始化。
const修飾范圍
- 修飾變量與對象,使其成為一般常量與對象常量
- 修飾函數的參數與返回值
- 修飾成員函數的函數體,指類的成員函數
const使用方法
修飾變量與對象
應當注意,除去指針類型,<類型> const與const <類型> 實質都為const <類型>。
但是,例如 int* const 和 const int* 不同,下面會講解。
- 修飾常用變量
const int a = 2; const double b = 1.23; const bool c;//錯誤,c需要設定初始值
//int const 與 const int 並無本質區別,實質都是const int
- 修飾引用
const int a = 2; //int &b = a;錯誤,引用常量時,變量本身也要用const修飾 const int& b = a; b = 3;//錯誤,const修飾當然不能為左值
- 修飾數組,注意數組中的元素被修飾為const,不能作為左值
const int a[4] = { 1,2,3,4 }; const int b[2][2] = { {1,2},{3,4} }; //int const也一樣,以下語句錯誤,數據元素被修飾為const,不能為左值 a[3] = 1;b[0][0] = 3;
- 修飾指針,
注意指針常量與常量指針的區別
指針常量:不能通過指針來修改變量的值
常量指針:一直指向該變量,不能給該指針賦予其他地址
const <指針類型>
int a = 2;//最好使用const修飾,否則會被修改與目的不符 const int *p1 = &a; //int const *p1=&a也一樣 int *p2 = &a; //*p1 = 3;//錯誤,*p1為指針常量,不能為左值 p1 = p2;//OK,指針本身可以作為左值 a = 4;//雖然無法通過*p1改變值,但可以直接改變a的值,不推薦。
<指針類型> const
int a = 2, b = 3; int* const p1 = &a; int *p2 = &b; p1 = p2;//錯誤,p1為常量指針,該指針本身不能為左值 *p1 = 3;//OK,指針指向的變量可以為左值
- 修飾指針數組與數組指針
數組指針與指針數組簡介
int myarray[4] = { 1,2,3,4 }; int *p1 = 0, *p2 = 0; int* a[2] = { p1,p2 };//a是一個指針數組,數組中元素全部是 int* 類型的指針 int(*b)[4] = &myarray;//b是一個數組指針,b指向一個大小為4的數組 //由於b是一個指向大小為4的數組的指針,首先得到指向的數組:*b,再訪問其元素(*b)[pos] cout << (*b)[1] << " " << a[1];
const修飾
int myarray[4] = { 1,2,3,4 }; int *p1 = 0, *p2 = 0; const int* a[2]{ p1,p2 }; *a[0] = 0;//錯誤,數組中元素為指針常量,其指向的變量不能為左值 a[0] = 0;//OK,指針本身可以作為左值 int* const b[2]{ p1,p2 }; b[0] = 0;//錯誤,數組中元素為常量指針,指針本身不能為左值 *b[0] = 0;//OK,指針指向的變量可以為左值 const int(*b)[4] = &myarray; b = &myarray;//錯誤,b本身為一個指向大小為4的數組的指針,被修飾為const,不能作為左值
-
修飾對象與成員變量
class Myclass { public: Myclass(int a,int b) { this->a = a; this->b = b; } int a; int b; }; const Myclass a(1,2); a.a = 2;//錯誤,被const修飾的對象及其成員變量無法作為左值
注意修飾成員變量時,初始化構造函數必須寫在構造函數初始化列表中,而不能寫在構造函數體中
class Myclass { public: Myclass(int x, int y)//錯誤,不能在函數體內初始化 { this->a = x; this->b = a; } Myclass(int x,int y):a(x),b(a){}//OK在構造函數初始化列表中初始化 const int a; const int &b; static const int sc; }; const int Myclass::sc = 2;
- 修飾類中重載函數
class Myclass { public: void print() { cout << "print"; } void print() const { cout << "const print"; } }; const Myclass a; a.print();//const,const對象默認調用const重載函數 Myclass b; b.print();//默認調用非const重載函數
修飾函數的參數與返回值
- 修飾函數參數:被修飾的參數在函數體中生效,不同類型參數的作用在以上都可以找到
若是此處為非指針與引用常量,都在函數中傳遞實參的副本,無論怎么改變都不會影響實際的值,因此不討論。
若是此處為指針或是引用常量,都是實參本身傳遞,需要考慮保護實參本身
//保護實參本身不會被函數體修改 int mymax(const int& a, const int& b) { return a > b ? a : b; } //沒有保護 int mymin(int *a, int *b) { return *a > *b ? *b : *a; } int a = 2, b = 3; const int *p1 = &a, *p2 = &b; cout << mymin(p1, p2);//錯誤,*p1,*p2不能作為左值,而在mymin函數體中可能會被改變
- 修飾函數返回值
const char* getString(); char *str=getString();//錯誤,getString返回值被修飾為const const char *str=getString();//OK
修飾成員函數的函數體
const放在類成員函數的尾部,用於修飾該成員函數,函數體內不能讓類的成員變量作為左值
class Myclass { public: int getval() const { this->val = 2;//錯誤,不能改變類的成員變量 return this->val; } private: int val; };