底层const,指针指向的对象或者引用指向的对象是const,就是说*p是常量,p可修改
顶层const,指针本身const,即常量指针,p只读,*p可修改
点击此链接了解,更详细的顶层和底层const
原因:
(两个对象至少有一个对象含有底层const时,若没有相同的底层const时,不允许对象的复制(赋值))
所以编译器给你指出错误:就是丢失(discard)了标识符const!!!
常见的情况
#include<iostream>
int main()
{
const int a = 1;//a有底层const,
int & b = a; 非法!!!b无底层const,无相同的底层const,不允许赋值
合法的赋值是--> const int & b = a;
}
另外一种典型错误就是定义下面这张函数:
double&的返回值,没有const,但是对象是底层const
其成员也有底层const(对象只读,所以其成员也是底层const),没有相同的底层const,不允许赋值,请注意,
函数返回值是一个匿名的变量!!返回值的右值需要赋值给函数匿名的返回值(左值)
从const double 到double &
double & Student::operator[](int i) const
{ 把const scores[i]赋值给了double & 显然前者是由底层const,
但是返回值不是const double & , 只是double & ,
所以返回值(左值没有底层const)
return scores[i];
}
以后我一定记住了这个错误!!!
类似于
int a[10];数组名是const指针,数组元素非const
const int *p_1=a;这里p_1是非const,但是元素(*p_1)是const,如果允许下面这行p_2=p_1
int *p_2=p_1;将导致通过指针修改const元素的发生,所以p_2=p_1编译报错,和上面的const int 赋值给int & 是同一个问题
最后针对第二种函数的报错的解决办法因人而异
如果不想修改成员就加const在函数头后面 , 把前面返回值的引用符号&去掉
如果允许修改,那就去掉函数后面的const就可以了;