10、const和constexpr区别

首先理解常亮表达式。常量表达式是指值不会改变,并且在编译过程就能计算得到结果。

  1. const修饰的对象无法修改,constexpr对象在编译期间就确定且无法修改。
  2. constexpr变量,编译器在编译阶段验证变量是否为一个常量表达式。
  3. constexpr侧重变量初值编译阶段确定,且无法修改。如果认定变量是一个常量表达式,就把它声明称constexpr类型。
  4. 两者都必须初始化。

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

热门相关:超武穿梭   网游之逆天飞扬   寂静王冠   霸皇纪   刺客之王