一、常量(用const修饰的一个变量,使其变为一个不可修改的值)
const int a=4;
cout<<“a=”<<a<<endl;
a=8;
cout<<“a=”<<a<<endl;
这个程序会报错,因为修改了常量a的值
二、指针常量与常量指针
1)指针常量:
定义:
int * const p=&a;
这时候const修饰的是指针p,意思是p这个指针本身是常量,一旦指出去就不可以被更改
这个时候会报错
但是p指的这个变量可以通过p去修改。
2)常量指针
定义:const int * p=&a
同样的代码,我们试着改变一下指针的定义,会发现报错情况正好相反
这个时候看报错信息这个时候我们看报错信息(*p)是一个常量,意思是不能通过指针来改变a的值(因为const修饰的是(*p)。
但是我们发现可以改变指针p指向的地方(因为const修饰的不是p)
const int *const p(同时结合了上面两种,既不允许更更改指向的值,也不允许重新指向其他地方)
接着我们看一下上面的常指针只想的都是变量a的地址,也就说一个普通变量既可以被常指针指向又可以被普通指针指向,但是如果一个常量b只能被常指针指向,不能被普通指针指向,因为一个普通指针可能改变b的值。 这个之后可以类比常对象和常成员函数之间的关系,把对象类比成a b这样的量 把成员函数类比成指针量(其实是成员函数中的this指针)
三、拷贝构造函数
这里const的文章并不是很多,只是定义中涉及到const(例如const类
定义:Teacher(const Teacher &t);
当在对象中直接赋值的时候就会调用默认的复制构造函数进行赋值:
四、常对象、常成员函数、常对象指针、常引用
-
常对象就是在实例化一个对象的时候在对象的开头用const修饰,常对象内部的任何值都不可以被改变;
-
常成员函数就是在成员函数的末尾+空格+const(意味着在成员函数中的隐藏的*this指针被const修饰)常成员函数中不能改变任何变量的值。
-
常对象指针就是一个常指针指向了一个对象,不能通过该指针改变该对象中的任何值(其实就是在之前介绍的int类型的广义化)
-
常引用就是给一个对象起别名,但是不能通过这个引用名改变对象的值
-
注意:对于他们之间的调用关系:常对象只能调用常成员函数;非常对象既可以调用常成员函数,又可以调用非成员函数。 首先解释前者 对于常对象因为这个对象内所有成员的值都不允许改变,因此如果调用非const成员函数,这个函数本身可以改变成员值,因此此时调用非常危险,一旦成员函数做出改变成员的值,这就违背了const对象的初衷,因此C++禁止调用。就像你告诉儿子咱们家的钱你只能挣不能花,但是如果这个时候你调用一个又花又挣的儿子,他挣钱还好,但是他一旦花钱就会报错。 但是调用const成员函数那不就正好,都是不允许改变的。相当于你只调用了一个只会挣钱的儿子,不存在他花钱的情况,双重保险。 接着我解释后者,对于普通对象因为这个对象的值可以被改变,如果调用普通的成员函数那就没问题,即可读也可写,如果调用常成员函数,对象本身是拥有读写权限的,是函数只做读操作,这是没问题的,就想你告诉你儿子咱们家的钱你既可以花也可以挣,但是你儿子只挣不花,这是没毛病的。
-
常对象指针(默认是修饰*p)参考常对象。
-
常引用也是一个道理
-
另一种情况(ClassType * const p)这种情况允许改变指向对象的值,但是不能重新指向;
代码参考如下:
class Coordinate{
private:
int m_iX;
int m_iY;
public:
void set(int x,int y){ //普通成员函数
m_iX=x;
m_iY=y;
}
int getX(){ //普通成员函数
return m_iX;
}
int getY(){ //普通成员函数
return m_iY;
}
void printf() const{ //常成员函数
cout<<"("<<m_iX<<","<<""m_iY<<")"<<endl;
}
} ;
int main(){
Coordinate coor(3,5); //普通对象
const Coordinate coor1; //常对象
const Coordinate &coor2=coor; //常对象引用
const Coordinate *p=&coor; //常对象指针
Coordinate * const pr=coor;
Coordinate coor3(3,6);
pr=&coor3//报错 因为此时const修饰的是p指针,一旦指出去之后不能再更改。
coor1.getX(); //× 因为在参数中省略的this指针是拥有读写权限的,coor1是常对象只有读权限。这样做非常危险,一旦成员函数中做出了写的操作,就逻辑不通,因为coor2是一个常对象,该引用不允许修改对象内任何成员的值。所以C++就不会让编译通过。
coor2.getX(); //× 因为在参数中省略的this指针是拥有读写权限的,coor2是常引用只有读权限。这样做非常危险,一旦成员函数中做出了写的操作,就逻辑不通,因为coor1是一个常引用,该引用不允许修改对象内任何成员的值。所以C++就不会让编译通过。
p->getX(); //× 因为在参数中省略的this指针是拥有读写权限的,p指针是一个常对象指针,这个指针所指向的变量的值不能修改,因此只有读权限。所以跟上述常引用一样不会通过
coor.printf(); //√ 都是拥有读写权限的普通调用
coor1.printf(); //√ 常成员函数被常对象所调用,都只是拥有读权限,在printf里面的this指针是一个常指针,coor是一个常对象,this就表示coor1。
coor2.printf(); //√ 常成员函数被常引用对象所调用,都只是拥有读权限,在printf里面的this指针是一个常指针,coor是一个常引用,this就表示coor所引用的对象。
}