一、const修饰指针变量
const修饰指针是修饰const后面(右边)所跟的部分。例如:
1、int *const p const修饰p,p的指向不可修改
2、const int* p或int const *p const修饰*p,*p不能做左值
3、const int **p const修饰**p
与const修饰的指针之间赋值注意:如果等号两边类型不一样,大多数情况下遵循“权限缩小”赋值规则。
但const int**= int **是不允许的,防止以下代码的出现
const int a = 10;
int *p ;
const int **q = &p ;
*q = &a ;
*p = 20 ;
int *const 在某些赋值中就可以看作int *。例如const int* = int *const 和 int * = int *const
错误赋值举例:
1、int * = const int *错误
int a = 10 ;
const int *p = &a ;
int *q = p ;
2、int ** = int *const*错误(引用的底层实现就是取地址)
int a = 10 ;
int *const p = &a ;
int *&q = p ;
3、int *const * = const int**错误
int a = 10 ;
const int *p = &a ;
int *const* q = &p ;
二、const与类
1、const与成员变量:由于构造函数执行的是赋值操作,所以const修饰的成员变量的初始化应放在初始化列表中。如:
class Test
{
public:
Test(int mdata = 0):data(mdata)
{}
private:
const int data;
};
2、const与成员方法(常方法)、const与对象(常对象):
常方法不能调用普通成员方法,普通成员方法可以调用常方法;
常对象不能调用普通成员方法,常对象只能调用常方法。
class Test
{
public:
Test(int mdata = 0):data(mdata)
{}
void Show()
{
int val = Get_val();
cout << "This is show : "<< val << endl ;
}
int Get_val()const
{
return data ;
}
private:
const int data;
};
int main()
{
Test test1(20);
test1.Show();
return 0 ;
}
三、const在赋值运算符重载函数中修饰形参(常引用)
1、防止实参被修改
2、接收隐式生成的临时对象
Test& operator=(const Test& rhs)
{
if(this != &rhs)
data = rhs.data ;
return *this ;
}
四、const修饰的变量真的不能修改吗
最后,我想测试一下,看下面这段代码
const int a = 10 ;
int *p = (int *)&a ;
cout << *p << " " << a << endl ;
*p = 20 ;
cout << *p << " " << a << endl ;
结果:
我们看到,上面是想用强转指针去修改内存块的值。
修改了内存块,但为什么打印a的时候还是10?因为在编译的时候把a看作是一个常量,之后用到a的地方都用这个常量替代。
但是,作为优秀的程序员不应该使用这么危险的语法。当我们试图去修改const修饰的全局变量时,会导致系统抛出异常,十分危险。