1.const
在c++11之前只有const关键字,主要有两个作用:变量只读,修饰常量。
2.constexpr
在c++11中新添加了关键字constexpr(作用:用于修饰常量表达式) 常量表达式:由多个常量组成并在编译过程中就能得到计算结果的表达式。
C++从编写完毕到执行一共要经历4个阶段:预处理、编译、汇编、链接。
常量表达式和非常量表达式的计算时机不同:
- 非常量表达式只能在运行阶段计算出结果
- 常量表达式的计算发生在编译阶段
建议:
- 凡是表达“只读”语义的场景都使用const
- 表达常量语义的场景使用constexpr
- 其实在定义常量时const 和 constexpr都能使用
3.const 和 constexpr 在使用上可等价
const int a=666; //常量表达式
const int b=a+1; //常量表达式
constexpr int a=666; //常量表达式
constexpr int b=a+1; //常量表达式
注意:在c++中 constexpr 可以用来修饰内置的数据类型 ,但是不能直接用于修饰自定义的数据类型(直接修饰无效)
如果需要修饰自定义的数据类型可以这样写(可以在实例化自定义数据类型时使用constexpr)
如何将自定义的数据类型定义为常量:
struct Test{
int x;
int y;
};
void test01(){
constexpr Test t{1,2};
constexpr int x=t.x;
constexpr int y=t.y;
cout<<x<<endl;
cout<<y<<endl;
}
4.常量表达式函数
我们可以通过使用constexpr修饰函数的返回值,这种函数被称为常量表达式函数
要求:
- 函数必须要有返回值,并且return返回的表达式必须是常量表达式
- 函数在使用之前,必须有对应的定义语句
#include <iostream>
using namespace std;
constexpr int a=666; //常量表达式
constexpr int b=a+1; //常量表达式
struct Test{
int x;
int y;
};
constexpr int func(); //常量表达式函数声明
//声明要在定义之前
constexpr int func(){ //常量函数表达式定义
constexpr int c=100; //局部常量表达式
return c;
}
void test01(){
constexpr Test t{1,2};
constexpr int x=t.x;
constexpr int y=t.y;
cout<<x<<endl;
cout<<y<<endl;
func();
}
int main() {
test01();
system("pause");
return 0;
}
- 整个函数的函数体中不能出现除(using、typedef、static_assert、return)的非常量表达式语句
5.修饰模板函数
c++11中constexpr 可以用于修饰模板函数,但是由于模板中类型的不确定性,模板函数实例化后的函数是否符合常量表达式函数的要求也是不确定的。
- 如果模板函数实例化后不满足常量表达式函数的要求,那么constexpr会被自动忽略,这个函数称为一个普通函数。
6.修饰构造函数
常量构造函数:构造函数的函数体必须为空,并且采用初始化列表的方式为各个成员赋值
#include <iostream>
using namespace std;
class Person{
public:
constexpr Person(int age):m_age(age){
}
int m_age;
};
int main() {
constexpr Person p(25);
cout << p.m_age << endl;
system("pause");
return 0;
}