c/c++ const关键字详解
c/c++ const关键字详解
const修饰普通变量
const修饰基础数据类型的变量,如
const int a=10;,就是声明一个常量,不能修改该变量的值
c语言中,const只是一种编译器约束,它告诉编译器:“不要通过变量名修改这个变量的值”,但是并没有实现真正的只读内存保护,c语言中是可以通过指针修改const变量的值的,甚至可以通过强制类型转换修改const变量,但这些都是未定义行为
而c++ 中
const具有更强的类型约束和访问保护,编译器通常会将全局或静态const对象放入只读内存区(但标准并未强制要求),从而在语义上和物理上都防止修改
const修饰指针
有两种情况
const int * ptr = &a; int * const ptr = &a;
- 第一种const限制的是指针指向对象的值,即不能通过指针修改指向的对象的值(不允许
*ptr=5),但是可以修改这个指针的指向(允许ptr=&b);- 第二种const限制的是指针的值,即不能修改指针这个对象的值,也就是不能修改指针的指向,但是可以通过指针修改指向的对象的值;
这种指针的一个实例是类中的this指针,this指针只能指向当前这个对象,不能指向其他对象,但是可以通过this指针修改对象中的变量值
const修饰函数参数
void func(const int a)上面这个是使用const修饰了形参,但实际上这是没有意义的,因为我们一般真正想要保护的是调用这个函数时那个“实际数据”
通过const修饰指针或者引用是真正有意义的
void func(const char *var); void func(const Type &var);
- const修饰指针,调用函数的时候将数据的地址复制给var,通过const修饰禁止函数中通过var修改原变量的值;
- const修饰引用,引用传参,传递的是外部实参本身,首先避免了拷贝,提高了效率,其次通过const禁止修改变量值,也是有效的const;
const修饰函数返回值
const修饰函数返回值的实例不是很多
const int func();const修饰普通类型返回值,这是毫无意义的,因为返回的变量是临时变量,是右值,本身具有常量性
const修饰指针/引用类型的返回值
拿指针类型举例
const int* func(); const int *p = func(); // 正确 int *p = func(); // 错误func函数返回的是
const int*类型,第二行使用相应类型的变量来接收显然是没有问题的,但是第三行,用一个普通的非const的指针来接收const指针,理论上是可以通过p指针来修改指针所指向的值的,相当于将指针访问权限放大,不允许
特别指出一种const修饰返回值的使用场景——类中重载运算符,主要是为了防止连锁赋值中出现对临时值的修改
场景一,赋值运算符
operator=class A { public: A& operator=(const A &other) { // ... return *this; } };赋值运算符允许连锁赋值
a = b = c,所以返回的是A&类型,也就是允许c赋值给b再赋值给a场景二,算术运算符
operator+, operator-class A { public: A operator+(const A &rhs) const { A result; // ... return result; } };上面返回的是一个临时对象,如果不加const,可能会出现
a + b = c这种情况(合法但是毫无意义),a+b返回的是一个临时对象,不应该给它赋值,所以正确的应该是返回const A
const修饰成员变量
const修饰成员变量,表示是一个成员常量,不能被修改,只能在声明的时候直接赋值或者在初始化列表中赋值
class A { public: const int const_value1 = 100; const int const_value2; A(int x): const_value2(x) {} };
const修饰成员函数
前面提到了this指针是
Type* const this这样的指针,不能修改this的指向,但是可以通过this指针修改对象的值,也就是可以在成员函数中修改成员变量的值。使用const修饰成员函数,实际上就是将this限定为const Type* const this,表示在该成员函数中不能对调用对象的任何成员进行修改(被mutable关键字修饰的变量除外),起到保护对象的作用class A { public: void display() const { std::cout << val << std::endl; return val; } int val; };注意:
- 前面提过,读写权限只能被缩小,不能被放大,所以const对象只能调用const成员函数,不能调用非const成员函数,因为const对象不能被修改,如果const对象调用非const成员函数,非const成员函数是可以修改对象的成员值的,这是权限的放大,是错误的。非const对象可以调用非const成员函数和const成员函数,这是权限的缩小;
- const修饰的成员函数不能调用类中任何非const成员函数,因为非const成员函数可能对对象造成修改;
更多推荐

所有评论(0)