const限定符的含义是:修饰类型为常量,即用const限定符修饰的变量为不可改变的量,它可以作用于很多的类型上面,基本类型、结构体类型,指针等等
const修饰基本变量类型代表着被修饰的变量有且只能被初始化一次
int main(){ const int a; //没有进行初始化,会报错,必须进行初始化 return 0; }
int main(){ const int a = 10; //在定义的时候初始化 const int b; b = 10; return 0; }
int main(){ const int a = 10; float const b = 10.0; //const可以在变量类型前面,也可以在变量类型后面 a = 20; //初始化后不能赋值 b = 20.0; return 0; }
当一些有不需要修改的变量时,可以用const对其进行修饰,避免特殊操作对这些变量的修改,比如说国家的每个地区的邮编,他是一个定值,不需要去修改,为了防止这些变量被不当操作修改,可以使用const限定符修饰,当然也可以用枚举来实现,这边只是举一个例子
#include<iostream> const int POST_CODE_TO_CHANGSHA = 0; //长沙的邮编代表的值 const int POST_CODE_TO_BEIJING = 1; //北京 const int POST_CODE_TO_SHANGHAI = 2; //上海 int main(){ int a; std::cout<<"Please input the postcode:"; std::cin>>a; switch (a) { case POST_CODE_TO_CHANGSHA:{ std::cout<<"The postcode that you input is ChangSha\n"; break; } case POST_CODE_TO_BEIJING:{ std::cout<<"The postcode that you input is BeiJing\n"; break; } case POST_CODE_TO_SHANGHAI:{ std::cout<<"The postcode that you input is ShangHai\n"; break; } default:{ std::cout<<"The postcode that you input is incorrectly\n"; } } return 0; }
class Test01{ int a; int b; public: Test01(int a,int b):a(a),b(b){} void setA(int a) const{ //const放在方法后面 this->a = a; //这一行会报错, } void setB(int b){ this->b = b; } void set() const{ setB(3); setA(3); } };
const修饰方法后面,表明这个方法是不能够对类中变量进行更改的,并且不能在const修饰的方法里面调用非const方法,实质上其实是对this指针做了const限定,既然this都是const了,怎么能够修改this指针指向的对象的成员呢?,但是,如果在属性定义前面加一个mutable关键字,那就会有不一样的效果
class Test01{ mutable int a; int b; public: Test01(int a,int b):a(a),b(b){} void setA(int a) const{ //const放在方法后面 this->a = a; //这一行会报错, } void setB (int b){ this->b = b; } };
cv(const 与 volatile)类型限定符 - cppreference.com
可以看到这样的话就不会报错了!
至于原因我搜了一下资料
[源自stackoverflow](c++ - How to call a non-const method from a const method? - Stack Overflow)
当然在const方法中修改变量可以使用const_cast强制将this之指针转换为一个指向对象自身的指针,通过对这个指针的操作来更改变量的值
class Test01{ int a; int b; public: Test01(int a,int b):a(a),b(b){} void setA(int a) const{ //const放在方法后面 Test01* me = const_cast<Test01*>(this); me->a = a; //可以通过这个获取的迁移指针来在const修饰的方法中更改非const变量的值和调用非const修饰的方法 me->setB(10); } void setB (int b){ this->b = b; } }; //这个思路比较直观,但是一个小的缺点是实际消耗空间变大了,一个大的缺点是不能保证别的成员数据不被修改
从字面意思来说const pointer是指向地址一经初始化就不能够再指向其它地址的指针变量,而pointer to const是一个指向常量的指针,对于指针变量自身来说他是非const的,但是它指向的值可以是const修饰的也可以不是const修饰的,上代码
int main(){ int a = 10,b = 20; const int c = 30; //const pointer 常量指针,指针变量自身为常量 int *const p = &a; //必须在定义时进行初始化, //p = &b; 再次为p赋值的话会报错,p是一个常量指针,他只能指向一个唯一的地址,再也不能更改,这就是从一而终! //pointer to const 指针常量,指向常量的指针变量 const int *q; //指针常量可以不进行初始化,也可以不用管它 q = &a; q = &b; q = &c; //pointer to const 奇了怪了,怎么又能指向非const变量这,其实是这丫有点过度自信,以为自己指向的就是常量,所以就出现了 //类似于普通指针的操作 //int *r = &c; //非常量指针是不能够指向常量的,这样纸会报错的 return 0; }
其实这么总结吧
- const pointer的话指针变量自身是一个常量,它指向的地址只能初始化一次,并且一旦定义必须被初始化
- pointer to const的话是指针变量自身不是一个常量,它可以指向常量,这丫自己自己为自己指向的就是常量,看都不看一下,所以可以赋值多次,指向不同的地址!
建议按照英文来理解,不然中文定义有点绕