C++ 关键字之Const、Constexpr

Const

原理:
编译器将在编译过程中将所有用到该变量的的地方都替换成对应的值。

const string name = "Mr.Chen";

注意事项:

  1. const 声明常数类型。
  2. 可以进行读取,不可以进行修改。
  3. 只要不改变存储的数据,都是合法的。如下面代码
	const int num = 40;
	if (num)
	{
    
    
		/// <summary>
	}
	int numAdd = num + num;
  1. 不可以让非常量类型引用常量类型。
  2. 临时量的使用:
    什么是临时量?
    当编译器需要一个空间来暂存表达式的求职结果来临时创建的一个未命名的对象,叫做临时量对象,简称临时量。
    如下代码:
       
    代码1:
	int i = 10;
	const int& num = i;
	i = 1;
	cout << num << endl;

代码2:

	double d = 3.14;
	const int& i = d;
	d = 4.14;
	cout << i << endl;

代码1输出1,代码2输出3;
原因是对于代码1而言,是将const int& 绑定到一个普通的int对象上;
对于代码2中const int& i = d; 行代码而言需要将右侧类型转换成左侧类型,编译器会代码2代码编程如下形式:

	const int temp = d;//由双精度浮点数生成一个临时的整形常量
	const int& i = temp;//让i绑定这个临时量

所以我们修改d并不会影响到该临时量,也就不会影响到绑定到临时量的i

constexpr

什么是常量表达式?
常量表达式是指值不会改变并且在编译过程就能得到计算结果的表达式,一个对象(表达式)是不是常量表达式由它的数据类型初始值共同决定。
例子:

	const int max_files = 20;	//max_files是常量表达式
	const int limit = max_files + 1;	// limit是常量表达式
	int staff_size = 27;	// staff_size不是常量表达式     数据类型只是一个普通的int类型而不是const int
	const int sx = get_size();	// sx不是常量表达式    get_size()具体值只有到运行时才可以获取到

constexpr变量:

  1. 声明为constexpr类型的变量一定是一个常量,且必须用常量表达式进行初始化。
  2. constexpr类型的常量在编译时就得到初始值常量,原因因为必须用常量表达式进行初始化,而常量表达式在编译过程中就得到计算结果。
  3. 普通函数不可以作为constexpr变量的初始值,C++11新标准规定,允许用constexpr修饰的函数作为constexpr变量的初始值,这种函数应该足够简单以在编译时就可以计算其结果,但是constexpr修饰的函数返回值不一定是编译期常量。
constexpr int foo(int i)
{
    
    
    return ++i;
}

int main()
{
    
    
    int i = 10;
    // 成功调用
    array<int, foo(5)> arr;
    // 成功调用
    foo(i);
    // 错误
    array<int, foo(i)> arr1;
    return 0;
}

上面的代码中,第一次和第二次执行都是正确的,第三次执行会报错。

  • 第一次中,foo(5)使用的是常量表达式5,所以在编译期间就可以得出结果,从而确定array的大小,所以这个声明是正确的;
  • 第二次中,foo(i)使用的是变量,在运行时可以得到结果,所以这个调用是正确的;
  • 第三次中,foo(i)使用的是变量,在运行时才能得到结果,但array的声明要求在编译期就必须要确定其大小,且不能改变,所以这条代码是错误的。
    所以,对于constexpr修饰的函数,如果其传入的参数可以在编译期算出来,那么这个函数就会产生编译期的值。如果传入的参数不能在编译时期计算出来,那么constexpr修饰的函数就和普通函数一样了。

constexpr指针:

对于constexpr声明中定义了一个指针,那么constexpr仅对指针有效,对指针所指的对象无关

	const int* p = NULL;	// p是一个指向整形常量的指针
	constexpr int* q = NULL;	// q是一个指向整形的常量指针

原因就是constexpr将定义的对象置为了顶层const

什么是顶层const和底层const?
指针本身就是一个对象,它既可以指向另一个对象。因此,指针本身是不是常量和指向的是不是常量是两个相互独立的问题。顶层const表示指针本身是个常量,底层const表示指向的对象是一个常量。

const和constexpr的区别

const和constexpr的区别

转载地址:https://www.cnblogs.com/dn96/p/10118471.html

猜你喜欢

转载自blog.csdn.net/weixin_44081533/article/details/112788782