C--面向对象程序设计-第四章-类与对象(二)课件

上传人:n85ho7****4h85bh 文档编号:243141675 上传时间:2024-09-16 格式:PPT 页数:76 大小:885KB
返回 下载 相关 举报
C--面向对象程序设计-第四章-类与对象(二)课件_第1页
第1页 / 共76页
C--面向对象程序设计-第四章-类与对象(二)课件_第2页
第2页 / 共76页
C--面向对象程序设计-第四章-类与对象(二)课件_第3页
第3页 / 共76页
点击查看更多>>
资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,76,C+,面向对象程序设计,第,4,章 类和对象(二),4.1,自引用指针,this,例,4.1,this,指针的引例。,#,include,class A,public:,A(,int,x1), x=x1; ,void,disp,(),cout,x= x,endl,;,private:,int,x;,;,main(),A a(1),b(2);,cout, a: ;,a.,disp,();,cout, b: ;,b.,disp,();,return 0;,a.,disp,(),与,b.,disp,(),在存储时是同一个函数,它怎么区分是,a,调用还是,b,调用它呢?,1什么是,this,指针,this,指针是由系统在编译时自动产生的一个指向对象自身的指针。,this,是一个隐含于每一个类的,非静态成员函数,中的特殊指针。用于指向正在操作该成员函数的对象。,当一个对象调用成员函数时,编译程序先将对象的地址赋给,this,指针,然后调用成员函数。成员函数存取数据成员时,由隐含的,this,指针引用,通常不显式地使用,this,指针来引用数据成员。,例4.2,显示,this,指针的值。,#,include,class A,public:,A(,int,x1), x=x1; ,void,disp,( ),cout,a=ma;this-b=,mb,;,由于函数调用时,第一个参数是按照地址传递的,因此当对象,ob,调用函数,init(),时,,this,指针便指向,ob,,于是隐式指针,this,保证了成员函数,init( ),的操作对象确实是对象,ob。,何时显式使用,this,指针?,(1),当需要在一个成员函数内标识被该成员函数操作的对象时,就需要显式使用,this,指针。,#,include ,class Sample,int,x,y;,public:,Sample(,int,i=0,int j=0),x=i;,y=j;,void copy(Sample &,xy,);,void print(),cout,x“,”y,endl,;,;,void Sample:copy(Sample &,xy,),if(this=&,xy,) return;,/,通过判断,避免不必要的复制,*this=,xy,;,main(),Sample p1,p2(5,6);,p1.copy(p2);,p1.print();,(2)当成员函数的形参名与该类的数据成员同名时,必须用,this,指针来显式区分。,#,include ,class,sam,int,a, b;,public:,sam,(,int,a,int,b) ,this-,a=a;,this-,b=b;,cout,a,endl,; void print(),cout,a= a b= b,endl,;,;,main(),sam,s2(2,2);s2.print();return 0; ,this,指针的另外一个作用:获取对象自身。因为,this,指针的值是对象自身的首地址,,*,this,是指针所指向的对象,即当前对象。,如果一个类的成员函数返回值是*,this,,程序就可以用这个返回值去调用另外一个成员函数。,【举例】,#,include ,class Classroom,public:,Classroom(,int,n=100,double l=8.0,double w=6.0);,Classroom & set(,int,n,double l,double w);,void print();,private:,int,seats;,double length,width;,;,Classroom:Classroom(,int,n,double l,double w),seats=n0 ? n:100;,length=l0? l:8.0;,width=w0?w:6.0;,Classroom &,Classroom:set(,int,n,double l,double w),seats=n0 ?n:100;,length=l0? l:8.0;,width=w0?w:6.0;,return *this;,void Classroom:print() ,cout,width meters width and ,length meters length,seats seats. ,endl,;,main(),Classroom a101(80,6,4);,cout,Classroom a101 is ;,a101.print();,cout,set and print:,endl,;,cout,Classroom a101 is ;,a101.set(90,7.0,5.0),.,print();,return 0; ,this,指针,是一个,const,指针,不能在程序中修改它和给它赋值,是一个局部数据,它的作用域仅在一个对象内部,在系统中隐含存在。一般不必特别地去使用它。,4.2,对象数组与对象指针,4.2.1,对象数组,所谓对象数组是指每一数组元素都是对象的数组。,定义一个一维数组的格式如下,:,类名 数组名,下标表达式,;,例,4.4,对象数组的应用。,#,include,class exam,public:,void set_x(,int,n),x=n;,int,get_x(),return x;,private:,int,x;,;,int,main(), exam ob4;,int,i;,for (i=0;i4;i+),obi.set_x(i);,for (i=0;i4;i+),cout,obi.get_x() ;,cout,”,操作符。,例,4.7,对象指针的使用。,#,include,class exe,public:,void set_a(,int,a),x=a;,void show_a(),cout,xshow_a();,/,利用对象指针访问对象的成员,return 0;,2.,用对象指针访问对象数组,例如将例,4.7的,main(),改写为,:,main(),exe ob2,*p;,ob0.set_a(10);,ob1.set_a(20);,p=ob;,p-show_a();,p+;,p-show_a();,return 0;,4.3,向函数传递对象,本节内容中,把对象当作普通变量理解就行了,4.3.1,使用,对象,作为函数参数,-,值传递,4.3.2,使用,对象指针,作为函数参数,-,地址传递,4.3.3,使用,对象的引用,作为函数参数,-,形参值的改变就是改变实参值,例4.11,使用对象作为函数参数。,#,include,class,aClass,public:,aClass,(,int,n), i=n; ,void set(,int,n), i=n; ,int,get( ), return i; ,private:,int,i;,;,void,sqr,(,aClass,ob,),ob.set(ob.get()*ob.get();,cout,copy of,obj,has i value of ;,cout,ob.get()n;,main(),aClass,obj(10);,sqr,(,obj,);,cout,obj,.i is unchanged in main:;,cout,obj,.get( ),endl,;,return 0;,【例】对象指针作函数参数示例。,#,include ,class M,public:,M( ) x=y=0;,M(,int,i,int,j), x=i;y=j;,void copy(,M *m,);,void,setxy,(,int,i,int,j) x=i;y=j;,void print( ),cout,x“,”yx; y=m-y; ,void fun(,M m1,M *m2,); /,一般函数说明,main( ),M p(5,7),q; /,定义对象,q.copy(,&p,);,fun(,p,&q,);,p.print( );,q.print( );,以,p,对象的地址为实参,void fun(,M m1,M *m2,) /,一般函数定义,m1.,setxy,(12,15);,m2-,setxy,(22,25);,实参形参,形参,p,q,m1,m2,实参,5 7,0 0,5 7,2008,2008,过程,调用中,5 7,2008,2008,5 7,5 7,5 7,22 25,过程,调用后,例4.12,使用对象指针作为函数参数。,#,include,class,aClass,public:,aClass,(,int,n), i=n; ,void set(,int,n), i=n; ,int,get( ), return i; ,private:,int,i;,;,void,sqr,(,aClass,*ob,), ob-set(ob-get() * ob-get();,cout,Copy of,obj,has i value of ;,cout,get()n;,main(),aClass,obj(10);,sqr,(,&,obj,);,cout,obj,.i in main has been changed :;,cout,obj,.get() n; return 0;,例4.13,使用对象引用作为函数参数。,#,include,class,aClass,public:,aClass,(,int,n), i=n; ,void set(,int,n), i=n; ,int,get( ), return i; ,private:,int,i;,;,void,sqr,(,aClass,& ob,),ob.set(ob.get() * ob.get();,cout,Copy of,obj,has i value of ;,cout,ob.get()n;,main(),aClass,obj(10);,sqr,(,obj,);,cout,obj,.i in main() has been changed :;,cout,obj,.get() n;,return 0;,例,#,include ,class M ,public:,M( ) x=y=0;,M(,int,I,int,j) x=I;y=j;,void copy(,M &m,);,void,setxy,(,int,i,int,j) x=I;j=j;,void print( ),cout,x“,”y,endl,;,private:,int,x,y;,;,void M:copy(,M &m,) /,成员函数定义,x=m.x; y=m.y; ,void fun(,M m1,M &m2,); /,一般函数说明,void main( ),M p(5,7),q; /,定义对象,q.copy(,p,);,fun(,p,q,);,p.print( );,q.print( );,void fun(,M m1,M &m2,) /,一般函数定义,m1.,setxy,(12,15);,m2.,setxy,(22,25);,实参形参,形参,p,q,m1,m2,实参,5 7,0 0,5 7,过程,调用中,5 7,5 7,5 7,5 7,22 25,过程,调用后,4.4,静态成员,4.4.1,静态数据成员,在一个类中,若将一个数据成员说明为,static,这种成员称为静态数据成员。,与一般的数据成员不同,无论建立多少个类的对象,都只有一个静态数据的拷贝。从而,实现了同一个类的不同对象之间的数据共享,。,定义静态数据成员的格式如下,:,static,数据类型,数据成员名,;,例4.15,静态数据成员的使用引例。,#,include,#include,class Student,public:,Student(char *name1,char *stu_no1,float score1);,Student();,void show(); /,输出姓名、学号和成绩,void show_count_sum_,ave,(); /,输出人数、总成绩和平均成绩,private:,char *name; /,学生姓名,char *,stu,_no; /,学生学号,float score; /,学生成绩,static,int,count; /,统计学生人数,static,float sum; /,统计总成绩,static,float,ave,; /,统计平均成绩,;,Student:Student(char *name1,char *stu_no1,float score1 ),name=new charstrlen(name1)+1; strcpy(name,name1);,stu,_no=new charstrlen(stu_no1)+1; strcpy(stu_no,stu_no1);,score=score1;,+count; /,累加学生人数,sum=sum+score; /,累加总成绩,ave,=sum/count; /,计算平均成绩,Student:Student(),delete name;,delete ,stu,_no;,-count;,sum=sum-score;,void Student:show(),cout,n name: name;,cout,n,stu,_no: ,stu,_no;,cout,n score: score;,void Student:show_count_sum_,ave,(),cout,n count: count; /,输出静态数据成员,count,cout,n sum: sum; /,输出静态数据成员,sum,cout,n,ave,: ,ave,; /,输出静态数据成员,ave,int,Student:count=0; /,静态数员,count,初始化,float Student:sum=0.0; /,静态数员,sum,初始化,float Student:,ave,=0.0; /,静态数员,ave,初始化,void main(),Student stu1(Liming,990201,90);,stu1.show();,stu1.show_count_sum_ave();,Student stu2(Zhanghao,990202,85);,stu2.show();,stu2.show_count_sum_ave();,1,、静态变量属于类,为类创建的所有对象所公用。,2,、类中的非静态变量,在类创建对象时,不同的对象拥有各自的变量存储空间。,3,、静态变量可以实现同一类中不同对象间的数据共享。,有关静态成员变量的语法规定,静态成员变量要用,static,声明。,静态成员变量的初始化要在类外单独进行,而且要在对象定义之前,一般在类定义之后、,main(),之前初始化。,初始化的格式:,数据类型 类名,:,静态数据成员名,=值;,如,int,Student:count=0;,注意:初始化时数据成员名前面不加,static。,静态成员变量属于类,公有的静态成员变量可以用,类名,:,静态数成员名,的方式在类外直接调用。(也可通过,对象,调用,私有的静态成员变量不能在类外调用。),与普通静态变量一样,在编译时创建并初始化。在该类的任何对象被建立之前就已经存在。,静态成员变量实际代替了全局变量的作用。,例,4.16公有静态数据成员的访问。,#,include ,class,myclass,public:,static,int,i;,int geti,(),return i;,;,int myclass,:i=0;,main(),myclass,:i=200;,myclass,ob1,ob2;,cout,ob1.i=ob1.,geti,(),endl,;,cout,ob2.i=ob2.,geti,(),endl,;,ob1.i=300;,cout,ob1.i=ob1.,geti,(),endl,;,cout,ob2.i=ob2.,geti,(),endl,;,return 0;,4.17静态数据成员和一般数据成员的不同。,#,include ,class Student,public:,Student(),+count;,StudentNo,=count; ,void print(),cout,student,StudentNo, ;,cout,count=count,endl,;,private:,static,int,count;,int StudentNo,;,;,int,Student:count=0;,main(),Student student1;,student1.print();,cout,-,静态成员函数名,(,实参表,),例4.18,静态成员函数来访问静态数据成员。,#,include,#include,class Student,private:,char *name; /,学生姓名,char *,stu,_no; /,学生学号,float score; /,学生成绩,static,int,count; /,静态数据成员,统计学生人数,static float sum;,/,静态数据成员,统计总成绩,public:,Student(char *name1,char *stu_no1,float score1);,Student();,void show();,/,普通成员函数,输出姓名、学号和成绩,staticvoid show_count_sum();,/,静态成员函数,输出学生人数和总成绩,;,Student:Student(char *name1,char *stu_no1,float score1 ),name=new charstrlen(name1)+1;,strcpy(name,name1);,stu,_no=new charstrlen(stu_no1)+1;,strcpy(stu_no,stu_no1);,score=score1;,+count; /,累加学生人数,sum=sum+score; /,累加总成绩,Student:Student(),delete name;,delete ,stu,_no;,-count;,sum=sum-score;,void Student:show(),cout,n name: name;,cout,n,stu,_no: ,stu,_no;,cout,n score: score;,void Student:show_count_sum() /,静态成员函数,cout,n count: count; /,输出静态数据成员,cout,n sum: sum; /,输出静态数据成员,int,Student:count=0;,/,静态数据成员初始化,float Student:sum=0.0;,/,静态数据成员初始化,void main(),Student stu1(Liming,990201,90);,stu1.show();,Student:show_count_sum(); /,使用类名访问,静态成员函数,Student stu2(Zhanghao,990202,85);,stu2.show();,stu2.show_count_sum(); /,使用对象,stu2,访问,静态成员函数,有关静态成员函数,可以定义成内嵌的,也可类外定义,类外定义时不要,static。,一般用来访问全局变量或同一类中的静态变量。,私有静态成员函数不能被类外部函数和对象访问,使用静态成员函数可以在创建对象之前处理静态数据成员,这是普通函数所不能实现的功能。,静态成员函数没有,this,指针。一般不访问类中的非静态成员,(,变量、函数,),,访问时,要把对象作为参数传递。,例,4.19静态成员函数访问非静态数据成员。,#,include ,class small_cat,public:,small_cat(double w),weight=w;,total_weight+=w;,total_number+;,static void display(small_cat & w),cout,The small_cat weights ,w.weight,kgn; ,static void total_,disp,(),cout,total_number small_cat total weight;,cout,total_weight kg ,endl,;,private:,double weight;,static double total_weight;,static double total_number;,;,double small_cat:total_weight=0;,double small_cat:total_number=0;,main(),small_cat w1(0.9),w2(0.8),w3(0.7);,small_cat:display(w1);,small_cat:display(w2);,w1.display(w3);,w3.total_,disp,();,return 0;,4.5,友 元,友元既可以是不属于任何类的一般函数,也可以是另一个类的成员函数,还可以是整个的类。,4.5.1,友元函数,友元函数不是当前类的成员函数,而是独立于当前类的外部函数,但它可以访问该类的所有对象的成员,包括私有成员、保护成员和公有成员。,1.将非成员函数声明为友元函数,例4.22,友元函数的使用。,#,include,#include,class girl ,public:,girl(char *n,int,d),name=new charstrlen(n)+1;,strcpy,(name,n); age=d;,girl() delete name; ,friend void,disp,(girl /,声明友元函数,private:,char *name;,int,age;,;,void,disp,(girl &x) /,定义友元函数,cout,Girls name is x.name,age:x.agen; ,void main(), girl e(Chen,Xinwei,18);,disp,(e); /,调用友元函数,友元函数没有,this,指针!,一个函数可以定义为多个类的友元函数。,【例,4.,19,】(110页),2.将成员函数声明为友元函数,一个类的成员函数也可以作为另一个类的友元,这种成员函数不仅可以访问自己所在类对象中的所有成员,还可以访问,friend,声明语句所在类对象中的所有成员。,这样能使两个类相互合作、协调工作,完成某一任务。,例,4.24,一个类的成员函数作为另一个类的友元。,#,include,#include,class girl;,class boy,public:,boy(char *n,int,d), name=new charstrlen(n)+1;,strcpy,(name,n);,age=d;,void,disp,(girl ,/,声明,disp,(),为类,boy,的成员函数,boy(), delete name; ,private:,char *name;,int,age;,;,class girl,public:,girl(char *n,int,d), name=new charstrlen(n)+1;,strcpy,(name,n);,age=d;,friend void boy:,disp,(girl ,girl(), delete name; ,private:,char *name;,int,age;,;,void boy:,disp,(girl &x) /,定义友元函数,disp,(),cout,Boys name is name,age:agen;,/,访问,boy,类对象的成员,cout,Girls name is ,x.name,age:,x.age,n;,/,访问,girl,类对象的成员,void main(),boy b(Chen Hao,25);,girl e(Zhang,Wei,18);,b.,disp,(e);,程序运行结果如下,:,Boys name is Chen,Hao,age: 25,Girls name is: Zhang,Wei,age: 18,类的成员函数作为另一类的友元时,该类应该先定义,4.5.2,友元类,一个类也可以作为另一个类的友元。,例如,:,class Y ,/,;,class X ,/,friend Y; /,声明类,Y,为类,X,的友元类,/,;,一个类被声明为另一个类的友元时,它的所有成员函数都成为另一个类的友元函数。,【例】友元类的示例。,#,include ,class Sample,int,x;,public:,Sample(,int,a)x=a;,friend class Operation,; /,把类,Operation,当作友元,(好朋友),;,class Operation,public:,int,add(Sample& s1, Sample& s2), return s1.x+s2.x; ,int,subtract(Sample& s1, const Sample& s2),return s1.x-s2.x; ,;,int,main(),Sample s1(10) , s2(6);,Operation,obj,;,cout,obj,.add(s1, s2),endl,;,cout,obj,.subtract(s1, s2),endl,;,return 0;,4.6,类的组合,如果一个类的对象是另一个类的数据成员,则称这样的数据成员为对象成员(子对象)。例如,:,class A ,/.,;,class B,A a; /,类,A,的对象,a,为类,B,的对象成员,public:,/,;,使用对象成员要注意的问题是对象成员的初始化问题,即,类,B,的构造函数如何定义,?,例如有以下的类,:,class X,类名,1,对象成员名,1;,类名,2,对象成员名,2;,类名,n,对象成员名,n;,;,一般来说,类,X,的构造函数的定义形式为,;,X:X(,形参表,0):,对象成员名,1(,形参表,1),对象成员名,i(,形参表,i) ,对象成员名,n(,形参表,n),/ ,构造函数体,练习:写出程序的运行结果,#,include,class Object,int val,;,public:,Object( );/,构造函数,Object(,int,i );/,构造函数,Object( );/,析构函数,;,Object:Object( ) /,默认构造函数,val,=0;,cout,n Default constructor for Object.n;,Object:Object(,int,i)/,构造函数定义,val,=i;,cout,n Constructor for Object: ,val,endl,;,Object:Object( )/,析构函数定义,cout,n Destructor for Object: ,val,endl,;,class Container /,定义新类,它含,Object,的对象,private:,int,date;,Object one;/,对象成员,Object two;/,对象成员,public:,Container( );/,构造函数,Container(,int,i,int,j,int,k);/,构造函数,Container( );/,析构函数,;,Container:Container( )/,默认构造函数定义,date=0;,cout,n Default constructor for Container.n;,Container:Container(,int,i,int,j,int,k),:two(i),one(j), date=k;,cout,n Constructor for Container.n;,Container:Container( ),cout,n Destructor for Container.n; ,int,main( )/,主程序,cout,n. Entering main .n;,Container,obj,(5, 6,10);,cout,n. Exiting main .n;,return 0;,4-7,共享数据的保护,4.7.1,常引用,如果在说明引用时用,const,修饰,则被说明的引用为常引用。,常引用的说明形式如下,:,const,类型说明符,&,引用名,例如,:,int,a=5;,const,int,其中,b,是一个常引用,它所引用的对象不允许更改。,例4.28,常引用作函数形参。,#,include,int,add(const,int,& i,const,int,void main(),int,a=20;,int,b=30;,cout,a+b=add(a,b),endl,;,int,add(const,int,& i,const& j),return i+j;,4.7.2,常对象,如果在说明对象时用,const,修饰,则被说明的对象为常对象。,常对象的说明形式如下,:,类名,const,对象名,(,参数表,);,或者,const,类名 对象名,(,参数表,);,在定义对象时必须进行初始化,而且不能被更新。,例4.29,非常对象和常对象的比较。,#,include,class Sample ,public:,int,m;,Sample(,int,i,int,j) m=i; n=j;,void,setvalue,(,int,i) n=i; ,void,disply,(),cout,m=m,endl,;,cout,n=n,endl,;,private:,int,n;,;,void main(), Sample a(10,20); a.setvalue(40);,a.m=30; a.,disply,();,4.7.3,常对象成员,1.,常数据成员,使用,const,说明的数据成员称为常数据成员。,如果在一个类中说明了常数据成员,那么构造函数就只能通过初始化列表对该数据成员进行初始化,而任何其他函数都不能对该成员赋值。,例4.30,常数据成员举例。,#,include ,class Date ,public:,Date(,int,y,int,m,int,d);,void,showDate,();,const,int,private:,const,int,year ; const,int,month; const,int,day; ;,Date:Date(,int,y,int,m,int,d),:year(y),month(m),day(d),r(year) ,inline void Date:,showDate,(),cout,r=r,endl,;,cout,year.month.day,endl,;,void main(), Date date1(1998,4,28); date1.showDate(); ,2.,常成员函数,在类中使用关键字,const,说明的函数为常成员函数,常成员函数的说明格式如下,:,类型说明符 函数名,(,参数表,),const;,const,是函数类型的一个组成部分,因此在函数的实现部分也要带关键字,const。,例4.31,常成员函数的使用。,#,include ,class Date ,public:,Date(,int,y,int,m,int,d);,void,showDate,();,void,showDate,() const,;,private:,int,year, month, day;,;,Date:Date(,int,y,int,m,int,d):year(y),month(m),day(d), ,void Date:,showDate,(),cout,ShowDate1:,endl,;,cout,year.month.day,endl,;,void Date:,showDate,() const,cout,ShowDate2:,endl,;,cout,year.month.day,endl,;,main(),Date date1(1998,4,28);,date1.,showDate,();,const Date date2(2002,11,14);,date2.,showDate,();,【练习】,写出程序的运行结果。,class A,public:,A();,A(,int,i,int,j);,A();,void Set(,int,i,int,j)a=i;b=j;,private:,int,a,b;,;,A:A( ), a=b=0;,cout,Default constructor,called.n;,A:A(,int,i,int,j),a=i;b=j;,cout,Constructor :a=a,b=b,endl,;,A:A(),cout,Destructor called.,a=a,b=b,endl,;,void main(),cout,Starting1n;,A a3;,for(,int,i=0;i3;i+),ai.Set(2*i+1,(i+1)*2);,cout,Ending1n;,cout,starting2n;,A b3=A(1,2),A(3,4),A(5,6);,cout,Ending2n;,【练习】,写出程序的运行结果。,class B,int,x,y;,public:,B();,B(,int,i);,B(,int,i,int,j);,B();,void print( );,;,B:B(), x=y=0;,cout,Default constructor,called.n;,B:B(,int,i),x=i; y=0;,cout,Constructor1 called.n;,B:B(,int,i,int,j),x=i;y=j;,cout,Constructor2 called.n;,B:B(),cout,Destructor called.n;,void B:print(),cout,x=x,y=y,endl,;,void main(),B *,ptr,;,ptr,=new B3;,ptr,0=B();,ptr,1=B(5);,ptr,2=B(2,3);,for(,int,i=0;i3;i+),ptr,i.print();,delete,ptr,;,
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 教学培训


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!