14.3常成员const修饰符常数据成员常函数成员21.const修饰符类的对象也可以在定义时由const修饰,我们称为常对象。常对象的语法格式为:constclass_Typeobject_name;或class_Typeconstobject_name;常引用的语法格式为:constdata_type&reference_name;3常对象引用作为函数成员的形参classC{public:voidsetName(conststring&n){name=n;}//..stringname;};一般形参作为某种类的对象并不希望被改变值时常常使用常对象引用作为参数.#includeiostreamusingnamespacestd;voiddisplay(constint&d);intmain(){intd(2008);display(d);return0;}voiddisplay(constint&d){d=d+5;//错误!常引用不能被改变值。coutdendl;}52.常数据成员使用const说明的数据成员我们称为常数据成员。如果一个类中存在常数据成员,那么任何函数成员都不能对该成员赋值;常数据成员不和其他数据成员一样,它只能在构造函数的初始化列表位置进行初始化。6classC{public:C(){x=-1;c=0;}private:intx;constintc;};classC{public:C():c(0){x=-1;}private:intx;constintc;};×7类的任何数据成员都可以在构造函数的初始化部分初始化,而常数据成员只能在此处被初始化。classC{public:C():c(0),x(-1){}private:intx;constintc;};类的数据成员的初始化的顺序是与数据成员声明的顺序一致的;与构造函数的初始化部分的先后顺序无关。#includeiostreamusingnamespacestd;classPoint{public:Point(doublenew_x,doublenew_y);Point(constPoint&p);voiddisp();private:doublex;constdoubley;//常数据成员y};Point::Point(doublenew_x,doublenew_y):y(new_y)//初始化列表初始化常数据成员y{x=new_x;}Point::Point(constPoint&p):y(p.y)//初始化列表初始化常数据成员y{x=p.x;}voidPoint::disp(){cout该点的坐标为:(x,y)endl;}intmain(){Pointp1(1,2),p2(p1);p1.disp();p2.disp();return0;}113.常函数成员被const修饰的函数成员我们称之为常函数成员。说明格式为:return_typefunction_name(formalparameterslist)const;const关键字可以被用于参与对重载函数的区分。在这里const是函数的一个组成部分,和friend、inline关键字不同,在函数定义时也需要加上const关键字。12classC{public:voidset(intn){num=n;}intget()const{returnnum;}private:intnum;};Get函数成员只能对类的数据成员进行只读操作,不能进行修改。13classC{public:voidm1(intx)const{m2(x);}//Error!voidm2(intx){dm=x;}private:intdm;};14classC{public:voidset(conststring&n){name=n;}conststring&get()const{returnname;}private:stringname;};#includeiostreamusingnamespacestd;charstr[20]=GoodMorning!;char&rep(intk){returnstr[k];}intmain(){rep(4)='_';coutThestringis:strendl;return0;}#includeiostreamusingnamespacestd;classPoint{public:Point(doublenew_x,doublenew_y);Point(constPoint&p);voiddisp();voiddisp()const;private:doublex;constdoubley;};Point::Point(doublenew_x,doublenew_y):y(new_y){x=new_x;}Point::Point(constPoint&p):y(p.y){x=p.x;//y=p.y;}voidPoint::disp()const{cout您正在调用一个常函数成员,;cout该点的坐标为:(x,y)endl;}voidPoint::disp(){cout该点的坐标为:(x,y)endl;}intmain(){Pointp1(1,2),p2(p1);constPointp(4,5);//p为常对象p1.disp();p2.disp();p.disp();//p调用常函数成员dispreturn0;}程序运行结果为:该点的坐标为:(1,2)该点的坐标为:(1,2)您正在调用一个常函数成员,该点的坐标为:(4,5)194.4指向对象的指针对象指针this指针201.对象指针指针如果指向的是类的对象,则该类称之为对象指针。对象指针遵循一般变量指针的各种规则。classname*对象指针名;Person*p_Person;Personp1;p_Person=&p1;Personp1,*p_Person=&p1;p_Person-set_name(“LiMing”);p_Person-set_age(20);p_Person-disp();212.this指针this指针是一个隐含于每一个类的函数成员中的特殊指针(包括构造函数和析构函数)。它用于指向正在被函数成员操作的对象。Person::Person(stringnew_name,unsignednew_age){name=new_name;age=new_age;}Person::Person(stringnew_name,unsignednew_age){this-name=new_name;this-age=new_age;}234.5静态成员与友元2013.11.12静态数据成员静态函数成员友元函数友元类241.静态数据成员静态数据成员的定义静态数据成员的初始化静态数据成员的访问25定义格式staticdatatypevariablename;初始化:datatypeclassname::variablename=some_value;classPerson{public:voidset_name(stringnew_name);voidset_age(unsignednew_age);stringget_name(){returnname;}unsignedget_age(){returnage;}voiddisp();voidwalk(){}voidoperate(){}private:stringname;unsignedage;staticintcount;//定义静态数据成员count};intPerson::count=0;//使用域限定符在类外初始化静态数据成员27注意:数值型静态数据成员默认值为0,即类外初始化count语句可以写为:intPerson::count;但该语句不能省略。静态数据成员不影响对象所占用的内存空间。28静态数据成员的访问:通过类名及域限定符直接访问;通过对象名访问。静态成员的static与静态存储的static是两个概念,前者是在类的范畴内,后者指内存空间的位置以及作用域的限定。29intmain(){Personp;p.count=3;coutp.coutendl;Person::count=5;coutPerson::countendl;}302.静态函数成员静态函数成员和其他函数成员一样,不属于类的任何对象。但它和其他函数成员的不同之处在于,静态函数成员只能改变类的静态成员(包括静态数据成员和静态函数成员),其他函数成员则可以访问类的所有成员。staticreturn_typeFunction_name(formalparameterslist);31和类的其他函数成员一样,静态函数成员既可以定义在类内作为静态内联函数成员,也可以在类内声明,在类外定义.在类外定义时static不用再写。classAccount{public://interfacefunctionvoidapplyint(){amount+=amount*interestRate;}staticdoublerate(){returninterestRate;}staticvoidrate(double);//setsanewrateprivate:stringowner;doubleamount;staticdoubleinterestRate;staticdoubleinitRate();};Accountac1;Account*ac2=&ac1;doublerate;rate=ac1.rate();rate=ac2-rate();rate=Account::rate();#includeiostream#includestringusingnamespacestd;classPerson{public:Person(stringnew_name,unsignednew_age);Person(constPerson&p);Person(){count++;}voidset_name(stringnew_name);voidset_age(unsignednew_age);stringget_name(){returnname;}unsignedget_age(){returnage;}voiddisp();staticintgetCount();private:stringname;unsignedage;staticintcount;//定义静态数据成员count};intPerson::count=0;//使用域限定符在类外初始化静态数据成员Person::Person(stringnew_name,unsignednew_age){name=new_name;age=new_age;count++;}Person::Person(constPerson&p){name=p.name;age=p.age;count++;}intPerson::getCount()//静态函数成员在类外定义{returncount;}intmain(){Personp1,p2,p3;Personp4(xiaoming,21),p5(p4);cout”当前Person类对象的个数为:”;coutPerson::getCount()endl;return0;}353.友元函数和友元类友元提供了不同类或对象的函数成员之间、类的函数成员与一般函数之间进行数据共享的机制。通过友元机制,一个普通函数或者类的函数成员可以访问到封装在某一个类的私有数据成员,即把数据的隐藏打开了一个小窗口,从中看到类的一些内部属性;友元在一定程度上破坏了封装,这需要设计者在共享和封装之间找到一个平衡。cla