blog:cpp:basic_const

基础语法 - const限定符

把引用绑定到const对象上,称之为对常量的引用,不能通过对常量的引用修改它所绑定的对象。

引用的类型必须与其所引用的对象的类型一致,但是对于const的引用有如下例外。

在初始化常量引用表达式时允许用任意表达式作为初始值,只要该表达式的结果能转换为引用的类型即可。

例:

int i = 42;
const int &r1 = i;    // 将const int& 绑定到一个普通的int对象上
const int &r2 = 42;
const int &r3 = i * 2;

double dval = 3.14;
const int &ri = dval;

cout << r1 << endl;   // r1为42
cout << ri << endl;   // ri为3

i = 100;
dval = 5.3;

cout << r1 << endl;   // r1为100
cout << ri << endl;   // ri为3

ri引用了一个int类型的数,但dval确实double类型,为了让ri绑定一个整数,编译器把上述代码变成了如下形式:

const int temp = dval;
const int &ri = temp;  // ri绑定了一个临时对象, 所以改变dval的值并不会改变ri的值。

不能定义 int &ri = dval;, 因为非常量引用意味着可以改变dval的值,由于类型不同,所以这种行为是非法的。

允许把指针本身定义为常量。常量指针必须初始化,一旦初始化完成,则它的则就不能再改变了。

* 放在const关键字之前用以说明指针是一个常量。(不变的是指针本身的值,而并非指向的那个值)

例:

int errNumb = 0;
int *const curErr = &errNumb;   // curErr 将一直指向errNumb
const double pi = 3.14159;
const double *const pip = &pi;  // pip是一个指向常量对象的常量指针

指针本身是一个对象,它又可以指向另一个对象。因此,指针本事是不是常量以及指针所指的是不是一个常量是两个相互独立的问题。

顶层const (top-level const) 表示指针本身是一个常量。

底层const (low-level const) 表示指针所指的对象是一个常量。

更一般的,顶层const 可以表示任意对象是常量,这一点对任何数据类型都适用。

例:

int i = 0; 
int *const p1 = &i;        // 不能改变p1的值, 这是一个顶层const
const int ci = 42;         // 不能改变ci的值, 这是一个顶层const
const int *p2 = &ci;       // 允许改变p2的值, 这是一个底层const
const int *const p3 = p2;  // 靠右的const的顶层const, 靠左的是底层const
const int &r = ci;         // 用于声明引用的const都是底层const

尽管可以使用const 来定义常量表达式,例如:

const int max_files = 20;
const int limit = max_files + 1;

但是在一个复杂的系统中,很难分辨一个出是指是不是常量表达式。

c++11 规定,允许将变量声明为constexpr 类型,以便编译器来验证变量的值是否是一个常量表达式, 例如:

constexpr int mf = 20;
constexpr int limit = mf + 1;
constexpr int sz = size();       // 只有当size() 是一个constexpr函数时,这才是一条正确的声明语句。

对constexpr函数的基本要求:

  1. 常量表达式函数体内只能有一条语句,并且是return语句
  2. return语句中,不能使用非常量表达式的变量、函数,且return的表达式也要是常量表达式。

例:

constexpr int func() {
    return 10;
}
  • blog/cpp/basic_const.txt
  • 最后更改: 2022/04/23 22:43
  • caodan