C++ const限定符


前言

本文主要记录const限定符在C++中的定义、使用及注意事项


一、const是什么?

const是C++中关键字,用于修饰变量与函数。对于修饰普通变量,const用于限定对变量本身的操作;对于修饰复合类型变量(引用、指针),const还可以限定对变量引用或指向的对象的操作;

二、使用与注意事项

1. 修饰变量

1.1 const与初始化

因为const对象一旦创建后其值就不能在改变,所以const对象必须初始化。
代码如下(示例):

const int i = 20;	// 正确:编译时初始化
const int j;		// 错误:未初始化

1.2 默认情况下,const变量仅在文件内有效

对于非const变量,由于它具有external特性,所以可以不在在变量的定义之前添加extern关键字;而const变量默认情况下,仅在文件内有效,所以,如果想要在多个文件之间共享const对象,必须在变量的定义之前添加extern关键字。
代码如下(示例):

// file1.cpp定义并初始化了一个常量,该常量能被其他文件访问
extern const int bufferSize = function();
// file1.h头文件
extern const int bufferSize; // 与file1.cpp中定义的是同一个

1.3 对常量的引用(reference to const)

形式(举例):const int &
字面含义:把引用绑定到常量对象上
解释:除了可以将该引用绑定到常量上,还可以将该引用绑定到非常量上。对常量的引用,只不过是引用的“自以为是”,它们觉得自己引用了常量,所以自觉地不去改变所引用对象的值(在编译期检测出来)。

const int ci = 10;
const int &r1 = ci;		// 将引用绑定到常量对象上

int i = 20;
const int &r2 = i;		// 将引用绑定到非常量对象上 

r2 = 10;				// 编译器认为r2引用的对象是常量,不可以改变所引用的对象的值,所以编译期间报错

1.4 常量与指针

1.4.1 指向常量的指针(pointer to const)

形式(举例):const int *
字面含义:指向常量的指针
解释:除了可以指向常量,还可以指向非常量。所谓指向常量的指针,只不过是指针的“自以为是”,它们觉得自己指向了常量,所以自觉地不去改变所指向的对象的值(在编译期检测出来)。

const int ci = 10;
const int *p1 = &ci;	// 指向常量

int i = 20;
const int *p2 = &i;		// 指向非常量

*p2 = 10;				// 编译器认为p2指向的对象是常量,不可以通过解引用的方式去改变指向对象的值,所以编译期间报错
1.4.2 常量指针

指针是对象而引用不是,所以可以将指针本身定为常量。常量指针必须初始化。
形式(举例):int * const p;
解释:仅仅定义了指针本身不可被修改,与指针指向的对象不能被修改无关。要想指向的对象不被改变,就要设计将指针指向的类型为常量,即使用1.4.1节讲到的指向常量的指针,不过,这也仅仅只能在编译期间起限制作用。

1.5 顶层const

如前面所述,指针本身是一个对象,它又可以指向另一个对象。因此,指针本身是不是常量与指针所指的是不是常量是两个独立的问题。用名词顶层const表示指针本身是个常量,而用名词底层const表示指针所指的对象是一个常量。
顶层const可以表示任意的对象是常量。底层const则与指针和引用等复合类型的基本类型部分有关。由于引用不是对象,所以对常量的引用(reference to const)不是顶层const,而是底层const

int i = 0;
int *const p1 = &1;			// 常量指针,指针本身是常量,这是一个顶层const
const int ci = 42;			// 变量自身是常量,这是一个顶层const
const int *p2 = &ci;		// 指针所指向的对象是常量,这是一个底层const
const int* const p3 = p2;	// 指针本身是常量,靠右的const是顶层const,指针指向的对象是常量,靠左的const是底层const
const int &r = ci;			// 对常量的引用都是底层const

注意:底层const的限制不容忽视。当执行对象拷贝操作时,等式左右两边的对象必须具有相同的底层const,或者两个对象的数据类型必须能够转化。一般的,非常量可以转化为常量,反过来则不成立。

int *p = p3;			// 错误:p3具有底层const定义,而p没有
p2 = p3;				// 正确:p2与p3都是底层const
p2 = &1;				// 正确:int* 转化为const int*

// 编译器只会让对引用对象的操作变得更加严格而不是宽松
int &r = ci;			// 错误:普通的int&不能绑定到int常量上(对常量操作变宽松,不可以)
const int& r2 = i;		// 正确:const int&可以绑定到一个普通int上(对非常量操作变严格,可以)

2.修饰函数

待补充


总结

未完待续

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值