首先理解常亮表達式。常量表達式是指值不會改變,並且在編譯過程就能計算得到結果。 const修飾的對象無法修改,constexpr對象在編譯期間就確定且無法修改。 constexpr變數,編譯器在編譯階段驗證變數是否為一個常量表達式。 constexpr側重變數初值編譯階段確定,且無法修改。如果認定變 ...
首先理解常亮表達式。常量表達式是指值不會改變,並且在編譯過程就能計算得到結果。
- 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