关键字const的用法

oneNeko 于 2022-05-19 发布

constconstant的简写,用来定义常量,它限定一个变量不允许被改变,产生静态作用。const最开始推出的目的是为了取代预编译指令,取长补短。

与define的对比

define是预编译指令,定义的宏是在预处理阶段展开的,而const是普通变量的定义,是只读变量,且是在编译运行阶段使用的。

define定义的是常量,define定义的宏在编译后消失了,它不占用内存,而const定义的常变量本质上仍然是一个变量,具有变量的基本属性,有类型、占用存储单元,除了不能作为数组的长度,用const定义的常变量具有宏的优点,而且使用更方便。

define定义的对象没有数据类型,编译器只能机械地进行字符替换,没有类型安全检查,即会出现边际问题或者是括号问题。而const定义的是变量,有数据类型。

使用规则

C 修饰示例

// const 修饰的是n1,因此n1不能再被修改
const int n1 = 1;

// const 修饰的是n2,因此n2不能在被更改
int const n2 = 2;

// n3是指针,const 修饰的是*n3。因此n3可变,n3指针指向的对象不可变
const int* n3 = &n1;
n3 = &n2; // 合法,修改了n3这个指针
*n3 = 3; // 不合法,尝试修改不可变对象

// n4是指针,const 修饰的是n4。因此n4不可变,n4指向的对象可变
int* const n4 = nullptr;

C++ 修饰示例

类的成员函数后面加const,表明这个函数不会对这个类对象的数据成员(准确地说是非静态数据成员)作任何改变。

class Shape {
	int x, y;

public:
	// const 修饰的是函数返回值,返回类型是int指针(int*),因此该int指针指向的对象不可修改,int指针可修改
	const int* f1() {
		return &x;
	}

	// const 没有修饰返回值,因此该int指针指向的对象可修改,int指针也可修改
	int* const f2() {
		x++;
		return &x;
	}

	// const 后面是成员函数体(可以理解为修饰this指针),因此成员函数体内部不允许对成员变量进行修改
	int f3() const {
		int z = 0;
		z++;// 合法
		x++;// 非法
		return x + z;
	}
};

const修饰的是类成员方法的函数体,所以代表的意思是类的成员变量是不允许修改的。我觉得这个 还和编译器有点关系,因为C++编译的时候一般会将this指针作为最后一个参数传进去(有些编译器会作为第一个参数传进行),所以上面的代码也可以理解为const修饰的是this指针

参考

const的修饰规则