看了一遍课本,但总感觉还是理解的不扎实,所以自己描述一遍,也便于自己以后复习。
常指针
形式 charconst p=st;(注意const的位置)
即常量指针,即指向一个特定数据时便无法更改,所以定义时就需要初始化。
但可以通过其来修改指向的变量。
intconst q=&j;
*q=2;
int k=0;
q=&k;// [Error] assignment of read-only variable ‘q’
指向常量的指针变量
const char *p=str;此时只是指此指针指向的是一个常量,所以该指针还可以指向其他的成员(包括非常量)但需要注意的是通过该指针修改该变量的值是不合法的,包括非常量
const int i=3,*p=&i;
p=1;// [Error] assignment of read-only location ’ p’
int j=1;
p=&j;
p=2;// [Error] assignment of read-only location ’ p’
常引用
引用被定义只是就需要被初始化,因为其只是依托在某个变量上,并没有和指针一样具有自己的存储空间,我是这样理解的,引用类似于寄生虫,无法单独存在。因此也无法定义一个引用数组(int &p【4】是错误的)。
而常引用,通常是为了在给函数传参时,防止其对改变量改变时,在前边所加的限定,(即为了防止实参被函数修改,所以他虽然和常指针的姓一样,但意义不同,反而类似于指向常量的指针,是指向的那个值无法改变)当我打出这句话时,我脑子里又有这样一个疑问,那不用引用,直接用普通参数不就可以了吗,但我又马上想到,使用引用的本质,是为了减少内存的消耗,所以必要时需使用。
常对象
即对某一个类实例化时,作用是其数据成员无法修改。(想了半天,好像也只有常指针有点不一样)
注意:
1.形式 Student const s1或者const Student s1,定义即需被初始化;
2.被定义为常对象后,其只能调用常成员函数 即用const限定的函数(想想const是在哪放着),即使某些不被标识的成员函数没有改变其数据成员,依旧无法调用,所以const其实也能作为函数重载的一种形式。
3.声明为常对象后,它的数据成员是不是都变成了常量,我在网上查阅,仿佛并不是,但是我们学校的某次慕课考试上确实是这样的。。。,我们的课本上也有写:常对象只能保证其数据成员是常数据成员,但不对成员函数有约束力;
4声明为常对象后,理论上其数据成员无法被修改,但是用 mutable 修饰后,可以在调用const修饰的成员函数进行修改改值。(听着有些匪夷所思,我还把它和常数据成员搞糊了) 例子如下
class bendan
{
private:
int wide;
mutable int length;
public:
void xiugai()const
{
wide=1;
length=2;
}
bendan(int w,int l)
{
wide=w;// [Error] assignment of member ‘bendan::wide’ in read-only object
length=l;//此语句没有报错
}
};
const bendan b1(0,0);
b1.xiugai();//这又告诉了我们,const函数竟然也能修改值
常数据成员
无法像普通常量一样定义时即初始化,所以在声明对象时必须用构造函数进行初始化,并且只能用初始化列表
在其他函数中对其修改是不合法的。
注意,此时是可以调用非const声明的函数的。
如果一定要修改,可以这样声明(额,此处说明,是我在独立回忆时与常对象弄到一起了便于以后自己再看时提醒自己,不能再错了!常数据成员无法改变!!!)
常成员函数
形式 int f()const{}
即const 在形参表后声明
注意
1 被定义为const后,其修改数据成员的值,将被视为非法
2.当其调用一个没有被const声明的函数时,非法
3.关键字const是函数的一部分,在函数声明和定义部分都必须包含,但调用时不需要(这是第二遍看课本时才加上去的)
class bendan
{
private:
int wide;
mutable int length;
public:
void change()const
{
wide=1;//[Error] assignment of member ‘bendan::wide’ in read-only object
length=2;//这个未报错。
}
bendan(int w,int l)
{
wide=w;
length=l;
}
};
bendan b1(0,0);
b1.change();