C++中的const和constexpr异同比较
constexpr是C++11引入的关键字,这个关键字用于指明其后面是一个常量,编译器在编译程序时会将其结果计算出来,而无需等到程序运行阶段,这样的优化极大的提高了程序的运行效率
我们知道,C++程序的执行过程,大概需要经历 编译,链接,运行这3个阶段. 这里值得特别关注的是,常量表达式和非常量表达式的计算时机并不同 => 非常量表达式只有在程序运行阶段时才会计算出结果, 而常量表达式的计算往往发生在程序的编译阶段, 这可以极大的提高程序的执行效率 => 因为表达式只需要在编译阶段计算一次,节省了每次运行时都需要计算一次的时间和资源消耗.
关键字constexpr表示的就是常量表达式. 在实际开发工作中,我们经常会用到常量表达式,比如数组的长度,就必须是一个常量表达式
int testArr1[3] = {0,1,2}; //ok
int testArr2[2 * 5] = {0}; //ok
int len = 10;
int testArr3[len] = {0}; //错误,因为len是一个整形变量,并不是常量表达式
2. constexpr还可以用来修饰函数的返回值 => 这样的函数称为 “常量表达式函数” => 这样的常量表达式函数必须满足3个条件
条件1: 函数必须有返回值,并且返回值不能是void
条件2: 整个函数的函数体中,除了可以包含using指令,typedef语句以及static_assert断言外, 就只能包含一条return返回语句,并且return返回的表达式必须是常量表达式
eg:
constexpr int fun(int x) { return 1 + 2 + x; }
条件3: constexpr修饰的常量表达式函数在使用之前(在调用它的位置之前),必须由对应的函数定义. 普通函数的调用只需要提前写好该函数的声明部分即可,函数的定义部分可以放在调用位置之后甚至其他文件中,但常量表达式函数在使用前,必须有该函数的定义
#include <iostream> using namespace std; constexpr int func(int x); int main() { int arr[func(2)] = {0}; //这里会报错,因为这里调用constexpr常量表达式函数func时,它只是在上面声明了,但是还没有定义。 ta的定义在main()函数后面,这是不行的 return 0; } constexpr int fun(int x) { return 1 + 2 + x; }
3. constexpr修饰类的构造函数
constexpr还可以用来修饰类的构造函数,这样做的目的是为了得到一个常量对象。 constexpr修饰的构造函数称为常量构造函数,常量构造函数有一个要求 => 构造函数的函数体必须为空,并且必须采用初始化列表的方式为各个成员赋值
#include <iostream> using namespace std;
struct Person
{
const char* _name;
int _age;
constexpr Person(const char* name, int age) : _name(name), _age(age)
{}
}
int main()
{
constexpr Person p{"武田",55};
cout << p._name << " " << p._age <<end1; // 武田 55
return 0;
}