1、用const
修飾函數的參數
-
參數是值傳遞
由於函數將自動產生臨時變量復制該參數,該參數無需保護,沒必要用
const
-
參數是指針傳遞或者引用傳遞
const
修飾的指針或引用所指向的值不可變。如果該參數只是起“被讀取”的作用,最好用const
修飾保護。
對於復合數據類型,最好使用引用傳遞,因為值傳遞的過程中要進行臨時對象的構造,復制,析構,這些都會造成時間和空間的浪費。
class list {
string name;
public:
void show(const list& l) {
cout << name;
}
}
2、用const
修飾函數的返回值
如果函數的返回值用const
修飾,接受這個返回值的變量也只能用const
修飾。
const int sum(int a, int b) {return a+b;}
int s = sum(1,1); //error
const s = sum(1,1); //編譯通過
3、const
成員函數
任何不會修改數據成員的函數都應該聲明為const
類型。如果在編寫const
成員函數時,不慎修改了數據成員,或者調用了其它非const
成員函數,編譯器將指出錯誤,這無疑會提高程序的健壯性。
class list {
string name;
public:
void show(list& l) const {
cout << name;
}
}
4 、const
對象
const
修飾的對象只能訪問const
函數和const
成員變量
class list {
string name;
public:
void show(list& l) const {
cout << name;
}
void show2(list& l) {
cout << name;
}
}
const list l;
l.show2(); //error
l.show(); //編譯通過
5 、與constexpr
區別
-
對於修飾Object來說
const
並未區分出編譯期常量(編譯時就可以確定的常量表達式)和運行期常量constexpr
限定在編譯期常量,也就是說,編譯器看見constexpr
就可以放心的對常量進行編譯期的優化了。
-
對於修飾函數來說
-
constexpr
修飾的函數,返回值不一定是編譯期常量#include <iostream> #include <array> using namespace std; constexpr int foo(int i) { return i + 5; } int main() { int i = 10; std::array<int, foo(5)> arr; // OK foo(i); // Call is Ok // But... std::array<int, foo(i)> arr1; // Error }
-
所以,對於constexpr
需要兩方面看待。
constexpr
修飾的函數,簡單的來說,如果其傳入的參數可以在編譯時期計算出來,那么這個函數就會產生編譯時期的值。但是,傳入的參數如果不能在編譯時期計算出來,那么constexpr
修飾的函數就和普通函數一樣了。不過,我們不必因此而寫兩個版本,所以如果函數體適用於constexpr
函數的條件,可以盡量加上constexpr
。
而檢測constexpr
函數是否產生編譯時期值的方法很簡單,就是利用std::array需要編譯期常值才能編譯通過的小技巧。這樣的話,即可檢測你所寫的函數是否真的產生編譯期常值了。
6、指向常量的指針(pointer to const)、常量指針指針(const pointer) 與 constexpr指針
-
指向常量的指針,又叫底層指針
-
作用:不能通過指針修改值,無論指向的值是否是const, 指針本身可以改變指向。
int a =1; const int b = 1; const int* p; p = &a; *p = 2;//錯誤 p = &b; *p = 2; //錯誤
-
-
常量指針,又叫頂層指針
-
作用:不能修改指針的指向,指針本身是常量,所以必須在聲明時初始化。
int a = 1; int b = 1; int* const p = &a; p = &b; //報錯
-
-
constexpr指針
- 作用和常量指針(頂層指針)一樣
6.5、類型別名與常量指針
typedef int* ip;
int a = 1;
const ip p; //等價於 int* const p; 也就是頂層指針,頂層指針必須初始化,所以這句是會報錯的
const ip p = &a; //正確
7、const引用
int const& a;
和 const int& a;
作用一樣,可以不加區分。
參考:https://www.zhihu.com/question/35614219/answer/63798713
https://www.jianshu.com/p/34a2a79ea947
《C++ primer》2.4節