首先理解常亮運算式,常量運算式是指值不會改變,并且在編譯程序就能計算得到結果,
- const修飾的物件無法修改,constexpr物件在編譯期間就確定且無法修改,
- constexpr變數,編譯器在編譯階段驗證變數是否為一個常量運算式,
- constexpr側重變數初值編譯階段確定,且無法修改,如果認定變數是一個常量運算式,就把它宣告稱constexpr型別,
- 兩者都必須初始化,
1、const
const int i = get_size(); // 運行時初始化
const iny j = 42; // 編譯時初始化
1.1 const物件僅在檔案內有效
如果要多個檔案共享一個const物件,需要加關鍵字extern
extern const int i =10;
1.2 頂層和底層const
頂層const指標自身無法修改
底層const指標可以修改
int i = 10;
int *const p1 = &i; // 頂層const:不能修改p1的值
const int *p2 = &i; // 底層const:不能修改p2指標指向
const int *const p3 = &i; // 底層+頂層const
const int &r = i; // 底層const:不能通過r修改i值
1.3 const代替#define
程式編譯程序氛圍:預處理、編譯和鏈接,#define在預處理階段接回展開,在編譯階段如果遇到錯誤,報錯資訊不明朗,
// 不推薦
#define e 2.7
// 推薦
const double e = 2.7;
1.4 修飾變數
const int sz = get_size(); // 雖然sz無法改變,但get_size() 編譯階段無法確定值,也就是說sz不是常量運算式
1.5 修飾指標
int i = 1;
int *const p1 = &i; // 頂層const
const int *p2 = &i; // 底層const
1.6 修飾函式
int size() const { curSize = 1; return curSize; }; // 錯誤:const函式不能修改任何類的資料成員
int size() const { setSize(); return curSize; } // 錯誤:const函式只能呼叫const函式
const int size() { return curSize; } // 函式回傳值為const型別
2、constexpr
C++11引入了常量運算式constexpr的概念,指的是值不會改變并且在編譯期間就能得到計算結果的運算式,
const int i = 1; // 常量運算式
const int j = i + 1; // 常量運算式
const int k = size(); // 當size()是一個constexpr函式時才是常量運算式,
2.1 修飾變數
constexpr int i = 20; // 字面量20是常量運算式
constexpr int j = i + 1; // mf + 1是常量運算式
constexpr int k = size(); // 只有當size是constexpr函式時,才是正確的
2.2 修飾指標
constexpr修飾指標,僅對指標有效,與指標所指物件無關
// j的定義必須放在函式體外
int j = 30;
// 函式體內
constexpr int *p1 = &j; // 等價于 int constexpr *p1 = &j;
*p1 = 40; // 正確
p1 = nullptr; // 錯誤,constexpr指標無法修改
2.3 修飾函式
constexpr無法修飾成員函式,只能作為函式回傳值型別,表明該函式回傳的是一個編譯期可確定的常量;constexpr 被隱式隱式指定為行內函式,只能在類的宣告中定義(.h檔案)
// 函式回傳值為constexpr型別
constexpr int getMaxSize() { return INT_MAX; } // 正確示例:回傳常量值
// 錯誤示例:vec.size()運行時確定,不能在編譯期決定
constexpr int getMaxSize()
{
std::vector<int> vec;
vec.push_back(1);
vec.push_back(2);
return vec.size();
}
// 正確:雖然看起來回傳的是變數,但編譯器可確定
constexpr int getMaxSize(int a, int b)
{
return a + b;
}
部分內容來源:(明明1109)原文鏈接:https://www.cnblogs.com/fortunely/p/14550145.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/546686.html
標籤:其他
上一篇:Java(單元測驗,反射)
下一篇:c++ 記憶體順序
