C++基础——const限定符
1、const限定符
const限定符的含义是:修饰类型为常量,即用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;
}
const放在方法后面
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 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的话是指针变量自身不是一个常量,它可以指向常量,这丫自己自己为自己指向的就是常量,看都不看一下,所以可以赋值多次,指向不同的地址!
建议按照英文来理解,不然中文定义有点绕