资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,8.1,类,的定义,一、类的概念,类是一种复杂的数据结构,它是将不同类型的数据和与这些数据相关的操作封装在一起的集合体。,定义类实际上是定义一种复杂的数据类型,而这种复杂的数据类型中不仅包含不同类型的数据,而且还要包含对这些数据的一些必要的操作。,类不仅具有封装性,而且还具有隐藏性,因此在定义类时还要对类中的某些成员进行隐藏。,第八章,类和简单对象,二、类的定义格式,类的定义格式反映了对类的描述。,定义类的一般格式:,/,说明部分,class,public:,private:,;,/,实现部分,第八章,类和简单对象,类的定义的举例,按照定义类的格式定义具体的类,描述日期类的具体定义:,/,说明部分,class TDate,public:,void SetDate(int y,int m,int d);,int IsLeapYear();,void Print();,private:,int year,month,day;,;,/,实现部分,void TDate:SetDate(int y,int m,int d),year=y;,month=m;,day=d;,int TDate:IsLeapYear(),return(year%4=0,void TDate:Print(),coutyear,month,dayendl;,1,、类定义的两种方法:,使用关键字,class,:默认权限,private,;,使用关键字,struct,:默认权限,public,;,2,、类的定义分为两部分:,说明部分和实现部分。,说明部分:类头和类体组成。,类头:,class,类体:一对花括号,加分号;,类体内说明该类中的各种成员。,实现部分:类的实现部分主要用来对一些在类体内只说明没定义的成员函数进行定义。,如类体内定义了所有的成员函数,则该类就没有实现部分(可以省略)。,3,、类的成员包括:数据成员和成员函数,数据成员代表类的属性;,成员函数是用来对数据成员进行操作的。,数据成员说明包括数据成员的名字及其类型。,成员函数可在类体内说明,在类体外的实现部分定义;也可在类体内对成员函数进行定义,定义在类体内的成员函数为内联函数。,4,、类体内的成员分,3,种访问权限:,公有,public,私有,private,保护,protect,。,公有成员不仅可被该类的成员函数访问,还可被类体外的程序访问。公有成员提供与外界接口功能。通常将类中的成员函数全部或部分定义为公有成员。,私有成员只有该类的成员函数或友元函数才可访问,类体外的程序是不可访问的。私有成员是封装体中被隐藏的部分。通常将全部或一部分的数据成员定义为私有成员。私有成员在类体外是不可见的。,保护成员在不同的条件下它具有公有成员或私有成员的特性。,5,、成员函数的定义,成员函数可以定义在类体内,也可以在定义在类体外。,定义在类体外时,类体内必须使用原型说明,成员函数在定义时前面必须加上类名限定,格式:,:,class Date,public:,void SetDate(int y,int m,int d),year=y;month=m;day=d;,int IsLeapYear(),return(year%4=0,void Print(),coutyear,month,dayendl;,private:,int year,month,day;,;,6,、定义类时应注意的事项,类体内的成员应说明其访问权限,使用,class,定义的类,其默认访问权限的成员为私有成员。在类体内定义公共或私有无先后顺序。,在类体内允许对成员函数进行定义,但不允许对数据成员赋值。,类中成员的类型是指数据类型,类中任何成员不能使用存储类说明符(如:,auto,extern,register,)进行修饰。类中数据成员的类型可以是,C+,语言所允许的所有类型,类体中可以有另一个类的对象作为成员。,注意:自身类的对象是不允许作该类成员的。,通常将类的定义部分放在一个头文件中,这是为了以后的使用方便。,回顾:,1,、习题回顾,2,、类的定义格式;,周一,3:20,做实验六 指针,下周一,3:20,做实验七 结构和联合,对象是属于某个类的对象。在对象定义之前应该先定义类。,一、对象的定义方法,对象的定义格式:,;,例如:,Data d1,d2,*pd,date20;,8.2,对象的定义和成员的表示,二、,对象的成员表示,一个对象的成员就是该对象所属类的成员,对象的成员与它所属类的成员相同,有数据成员和成员函数两种。,对象成员的表示使用运算符,.,和,-,。,一般对象成员使用,.,表示。格式:,.,.(),指向对象的指针的成员使用,-,表示,-,-(),或者:,(*).,(*).(),例如:类,Date,的对象,d1,的数据成员表示,d1.year,d1.month,d1.day,。,对象,d1,的,3,个成员函数表示,d1.SetDate(y,m,d),d1.Isyear(),d1.Print(),类,TDate,的对象指针,pd,的数据成员表示,pd-year,d1-month,d1-day,。,对象指针,pd,的,3,个成员函数表示,d1-SetDate(y,m,d),d1-Isyear(),d1-Print(),#include,class Date,public:,void SetDate(int y,int m,int d),year=y;month=m;day=d;,int IsLeapYear(),return(year%4=0,void Print(),coutyear,month,daySetDate(2000,2,8);,coutd1.IsLeapYear(),d2.IsLeapYear()endl;,d1.Print();,d2.Print();,例,8-1,分析程序输出结果,熟悉对象的定义和成员的表示方法。,8.3,构造函数和析构函数,创建对象时,系统将会自动调用构造函数对所创建的对象进行初始化,即使对象的数据成员获得初值。,对象的,初值是通过自动调用构造函数获取值。,对象的值可以通过赋值,或通过调用已有的成员函数来改变。,8.3,构造函数和析构函数,一、构造函数,1,、构造函数的基本特点是成员函数,除具有成员函数的特性之外,还有自身的特点。,该函数的名字与类名相同。,定义构造函数时不必给出类型。,该函数可以有一个参数或多个参数,也可以无参数无参数的构造函数称为默认构造函数。,该函数通常在创建对象时系统自动调用。,2,、构造函数的种类,构造函数按照参数不同可以分为以下几种。,默认构造函数无参数的构造函数,(),默认构造函数又分为两种:,1,st,系统自动提供的默认构造函数。当定义一个类时,类体内,2,nd,用户定义的不带参数的构造函数,它的函数体可以根据需要定义内容。,带参数的构造函数,类体中可以定义带参数的构造函数,(),复制构造函数和默认复制构造函数,(&),复制构造函数又称复制初始化构造函数。用来给对象初始化用,与一般构造函数的区别仅在于它是用一个已知对象来对创建的对象进行初始化,即用已知对象对创建对象初始化。,复制构造函数还具有两个作用:,1,st,当使用对象作函数的形参时,系统将自动调用复制构造函数用实参来初始化形参。,2,nd,当对象作函数返回值时,系统将自动调用复制构造函数用函数的返回值创建一个临时对象。,二、析构函数的功能和特点,析构函数也是一种特殊的成员函数。析构函数的功能是用来释放所创建的对象的,析构函数除了具有成员函数的特性外,还具有如下特点:,与构造函数相同的类名,与构造函数的区别是在类名前加字符,,表明它与构造函数的功能相反。,该函数没有参数,不能重载。定义析构函数时不必给出类型。,析构函数是被系统自动调用的。当一个对象结束它的生存期时,系统将自动调用其析构函数来释放该对象。,定义格式:,(),如果一个类中没有定义析构函数时,系统会自动生成一个默认析构函数,格式如下,:,(),三、对象的赋值,创建一个类的对象时,系统会自动调用构造函数对它进行初始化。可以通过赋值来改变一个对象的值,同一个类的两个对象之间可以赋值。对象赋值是通过赋值运算符进行的。,对象赋值的赋值运算符通常需要进行重载。(运算符的重载后面讨论),一个类中在没有对赋值运算符进行重载定义时,系统会产生一个默认的赋值操作,使用该操作可将一个对象的数据成员的值赋给另一个对象的对应的数据成员,这两个对象通常需要是同一个类的。,例如:,TDate1 d2(2003,2,7),d1;,d1=d2;,#include,class Date1,public:,Date1(int,int,int);,Date1(),coutDefault constructor called.n;,Date1(),coutDestructor called.tdayendl;,void Print();,private:,int year,month,day;,;,Date1:Date1(int y,int m,int d),year=y;,month=m;,day=d;,coutConstructor called.n;,例,8-2,分析程序输出结果,熟悉构造函数和析构函数的定义和用法。,void Date1:Print(),coutyear/month/dayendl;,void main(),static Date1 d1;,Date1 d2(2005,6,25);,coutd1 is;,d1.Print();,coutd2 is;,d2.Print();,例,8-2,分析程序输出结果,熟悉构造函数和析构函数的定义和用法。,#include,class Point,public:,Point(int i,int j),X=i;Y=j;,Point(Point,Point(),coutDestructor called.n;,int Xcood(),return X;,int Ycood(),return Y;,private:,int X,Y;,;,例,8-3,分析程序输出结果,熟悉拷贝构造函数的用法及对象赋值的含义。,Point:Point(Point&rp),X=rp.X;,Y=rp.Y;,coutCopy Constructor called.n;,void main(),Point p1(6,9);,Point p2(p1);,Point p3=p2,p4(0,0);,p4=p1;,coutp3=(p3.Xcood(),p3.Ycood()n;,coutp4=(p4.Xcood(),p4.Ycood()n;,例,8-3,分析程序输出结果,熟悉拷贝构造函数的用法及对象赋值的含义。,#include,class Point1,public:,Point1(int i,int j),X=i;,Y=j;,coutConstructor calld.n;,Point1(Point1,Point1(),coutDestructor called.n;,int Xcood(),return X;,int Ycood(),return Y;,private:,int X,Y;,;,Point1:Point1(Point1&rp),X=rp.X;,Y=rp.Y;,coutCopy Constructor called.n;,例,8-4,分析程序输出结果,熟悉拷贝构造函数的用法。,Point1&fun(Point1 Q),coutok!n;,int x=Q.Xcood()+5;,int y=Q.Ycood()-5;,Point1 R(x,y);,Point1,return rr;,void main(),Point1 M(5,7),P(0,0),S(0,0);,Point1 N(M);,P=fun(N);,S=M;,coutP=(P.Xcood(),P.Ycood()n;,coutS=(S.Xcood(),S.Ycood()n;,例,8-4,分析程序输出结果,熟悉拷贝构造函数的用法。,1,、类的定义格式;,2,、对象的定义方法;,3,、构造函数的功能、种类和特征;,4,、析构函数的功能和特点。,周一,3:20,做实验六 指针,下周一,3:20,做实验七 结构和联合,小结:,回顾:,1,、类的定义格式;,2,、对象的定义方法;,3,、构造函数的功能、种类和特征;,4,、析构函数的功能和特点。,下周一,3:20,做实验七 结构和联合,下周五,10:00,做实验八类和简单对象,#include,class Point1,public:,Point1(int i,int j),X=i;,Y=j;,coutConstructor calld.n;,Point1(Point1,Point1(),coutDestructor called.n;,int Xcood(),return X;,int Ycood(),return Y;,private:,int X,Y;,;,Point1:Point1(Point1&rp),X=rp.X;,Y=rp.Y;,coutCopy Constructor called.n;,例,8-A,分析程序输出结果,熟悉拷贝构造函数的用法。,Point1&fun(Point1 Q),coutok!n;,int x=Q.Xcood()+5;,int y=Q.Ycood()-5;,Point1 R(x,y);,Point1,return rr;,void main(),Point1 M(5,7),P(0,0),S(0,0);,Point1 N(M);,P=fun(N);,S=M;,coutP=(P.Xcood(),P.Ycood()n;,coutS=(S.Xcood(),S.Ycood()n;,例,8-A,分析程序输出结果,熟悉拷贝构造函数的用法。,#include,class Tpoint1,public:,Tpoint1(int x,int y),X=x;Y=y;,Tpoint1(Tpoint1,Tpoint1(),coutDestructor calledn;,int Xcoord(),return X;,int Ycoord(),return Y;,private:,int X,Y;,;,Tpoint1:Tpoint1(Tpoint1&p),X=p.X;,Y=p.Y;,coutCopy-initialization Constructor calledn;,例,8-6,分析程序输出结果,熟悉拷贝构造函数的用法。,#include tpoint1.h,Tpoint1 fun(Tpoint1 Q);,void main(),Tpoint1 M(12,20),P(0,0),S(0,0);,Tpoint1 N(M);,P=fun(N);,S=M;,coutP=P.Xcoord(),P.Ycoord()endl;,coutS=S.Xcoord(),S.Ycoord()endl;,例,8-6,分析程序输出结果,熟悉拷贝构造函数的用法。,8.4,成员函数的特性,类中包含两种成员:,1,、数据成员,2,、成员函数,1,一、类中数据成员类型的规定,1,、数据成员允许的数据类型:,数据成员可以是整型、浮点型等基本数据类型,也可以是结构、联合等构造数据类型,还可以是指针、引用。,2,、数据成员不能使用自身类的对象;,数据成员的存储类说明只能是静态类。,8.4,成员函数的特性,二、成员函数的特性,成员函数是在类体内被说明的函数,成员函数可以定义实现在类体内,也可以实现在类体外。成员函数具备一般函数的部分特性:,1,、成员函数的重载性,成员函数可以重载函数,但是在重载函数参数的类型、个数和顺序上要有区别。,2,#include,class AB,public:,AB(int i,int j),a=i;b=j;,AB(int i),a=i;b=i*i;,int Add(int x,int y);,int Add(int x);,int Add();,int aout(),return a;,int bout(),return b;,private:,int a,b;,;,int AB:Add(int x,int y),a=x;,b=y;,return a+b;,例,8-5,分析程序输出结果,熟悉成员函数重载的用法。,int AB:Add(int x),a=b=x;,return a+b;,int AB:Add(),return a+b;,3,void main(),AB a(5,8),b(7);,couta=a.aout(),a.bout()endl;,coutb=b.aout(),b.bout()endl;,int i=a.Add();,int j=a.Add(4);,int k=b.Add(3,9);,coutiendljendlkendl;,例,8-5,分析程序输出结果,熟悉成员函数重载的用法。,AB(int i,int j),a=i;b=j;,AB(int i),a=i;b=i*i;,4,8.4,成员函数的特性,二、成员函数的特性,2,、成员函数的内联和外联,5,类中成员函数定义在类体内时,称为内联函数;定义在类体外时,则称为外联函数。,外联函数是相对于内联函数而言的,外联函数的函数体是被调用的,而内联函数的函数体是被替换的。,如果将外联函数定义为内联函数则调用函数时,函数名前加关键字,inline,。,#include,class M,public:,M(int i,int j),a=i;b=j;,int fun1(),return a;,int fun2(),return b;,int fun3(),fun4();,private:,int a,b;,;,inline int M:fun3(),return fun1()+fun2();,例,8-6,分析程序输出结果,熟悉内联函数的定义方法。,inline int M:fun4(),return fun3();,void main(),M m(5,8);,int n=m.fun4();,coutnendl;,6,8.4,成员函数的特性,二、成员函数的特性,3,、成员函数可以设置默认参数,7,成员函数和普通函数一样可以设置默认参数。,默认参数的设置应该是从右到左。,#include,class A,public:,A(int i=8,int j=10,int k=12);,int aout(),return a;,int bout(),return b;,int cout(),return c;,private:,int a,b,c;,;,A:A(int i,int j,int k),a=i;b=j;c=k;,例,8-7,分析程序输出结果,熟悉给成员函数设置默认参数的用法。,8,void main(),A X,Y(5),Z(7,9,11);,coutX=X.aout(),X.bout(),X.cout()endl;,coutY=Y.aout(),Y.bout(),Y.cout()endl;,coutZ=Z.aout(),Z.bout(),Z.cout()endl;,例,8-7,分析程序输出结果,熟悉给成员函数设置默认参数的用法。,A:A(int i,int j,int k),a=i;b=j;c=k;,9,8.5,静态成员,静态成员是指类的成员是静态类的,与静态类对象是不同的概念。,静态成员分为静态数据成员和静态成员函数两种。,静态数据成员属于类,而不是属于每个对象,是该类中所有对象所共有的。存储上,静态数据成员被存放在一个公用的存储单元中。,静态数据成员的初始化是在类体外单独进行。静态数据成员实现该类多个对象之间的数据共享。,静态成员函数的实现只能直接引用静态成员。,10,8.5,静态成员,一、静态数据成员,1,、静态数据成员的说明方法和初始化:,静态数据成员定义在类体内,在定义时前边加关键字,static,。,例如:,class M,private:,int a;,static int b;,11,8.5,静态成员,一、静态数据成员,1,、静态数据成员的说明方法和初始化:,静态数据成员定义在类体内,但初始化在类体外进行。例如:,class M,private:,int a;,static int b;,int M:b=10;,12,8.5,静态成员,一、静态数据成员,静态数据成员初始化的方法:,:=,;,静态数据成员的引用方法:,:,13,2,、静态数据成员的特点,静态数据成员定义在类体内,初始化在类体外。初始化后才可以使用。,静态数据成员是属于类的,而不是使用某个对象的。静态数据成员是所有对象共享的,使用它可以节省内存。,引用静态数据成员可以使用类名,格式如下:,:,定义静态数据成员像定义一般数据成员一样,应该给出数据类型和访问权限。,静态数据成员的寿命较长,它被存放在内存的静态工作区。,14,#include,class MY,public:,MY(int i,int j,int k);,void PrintNumber();,int GetSum(MY m);,private:,int a,b,c;,static int s;,;,int MY:s=0;,MY:MY(int i,int j,int k),a=i;b=j;c=k;,s=a+b+c;,例,8-8,分析程序输出结果,了解静态数据成员的使用方法。,void MY:PrintNumber(),couta,b,cendl;,int MY:GetSum(MY m),return MY:s;,15,void main(),MY m1(2,3,4),m2(5,6,7);,m2.PrintNumber();,coutm1.GetSum(m1),m2.GetSum(m2)endl;,例,8-8,分析程序输出结果,了解静态数据成员的使用方法。,MY:MY(int i,int j,int k),a=i;b=j;c=k;,s=a+b+c;,int MY:GetSum(MY m),return MY:s;,16,二、静态成员函数,1,、静态成员,函数,的说明和定义,静态成员函数可以定义在类体内,也可以说明在类体内定义在类体外。,定义在类体外时,按照成员函数的定义格式,但不必加关键字,static,。,static,(),17,二、静态成员函数,2,、静态成员函数的引用方式,静态成员函数的实现可以直接引用静态数据成员,但不能直接引用非静态数据成员。非静态成员的引用需通过对象来实现。,使用类名和作用域运算符引用静态成员函数:,:(),使用对象引用静态成员函数的格式:,.(),17,二、静态成员函数,3,、静态成员函数的特点,静态成员函数具有不同于一般成员函数的特点:,定义静态成员函数的目的是为了处理类中的静态数据成员。因此,在没有对象存在的情况下,也可以调用静态成员函数。,由于静态成员函数是用于处理类的,因此不能使用,this,指针。,由于静态成员函数的程序代码在编译阶段就被分配内存空间了,因此不能被定义为虚函数。,18,#include,#include,class Student,public:,Student(char name1,int sco),strcpy(name,name1);,score=sco;,void total(),sum+=score;count+;,static double aver(),return(double)Student.sum/Student.count;,private:,char name20;,int score;,static int sum,count;,;,例,8-9,分析程序输出结果,学会静态函数的用法。,int Student:sum=0;,int Student:count=0;,19,void main(),Student stu5=Student(Ma,89),Student(Hu,90),Student(LU,95),Student(Li,88),Student(Gao,75);,for(int i=0;i5;i+),stui.total();,coutAverage=Student:aver()endl;,例,8-9,分析程序输出结果,学会静态函数的用法。,20,小结:,1,、数据成员的类型;,2,、成员函数的特性;,3,、静态数据成员;,4,、静态成员函数。,预习,常成员和友元函数,作业:,p229 8.4,读程序,#include,void main(),char*p1,*p2;,p1=abcxyz;,p2=abcstu;,a,b,c,x,y,z,0,a,b,c,s,t,u,0,while(*p1&*p2&*p2,+,=*p1,+,),;,cout*,-,p1-*,-,p2endl;,#include,void main(),char s=ABCDEFG;,char*p=s+2;,for(;ps+6;p+),coutpendl;,p=s-1;,for(int i(0);i=6;i+),cout*+p;,coutendl;,A,B,C,D,E,F,G,0,A,B,C,D,E,F,G,0,#include,class Point1,public:,Point1(int i,int j),X=i;,Y=j;,coutConstructor calld.n;,Point1(Point1,Point1(),coutDestructor called.n;,int Xcood(),return X;,int Ycood(),return Y;,private:,int X,Y;,;,Point1:Point1(Point1&rp),X=rp.X;,Y=rp.Y;,coutCopy Constructor called.n;,例,8-A,分析程序输出结果,熟悉拷贝构造函数的用法。,Point1&fun(Point1 Q),coutok!n;,int x=Q.Xcood()+5;,int y=Q.Ycood()-5;,Point1 R(x,y);,Point1,return rr;,void main(),Point1 M(5,7),P(0,0),S(0,0);,Point1 N(M);,P=fun(N);,S=M;,coutP=(P.Xcood(),P.Ycood()n;,coutS=(S.Xcood(),S.Ycood()n;,例,8-A,分析程序输出结果,熟悉拷贝构造函数的用法。,#include,class Tpoint1,public:,Tpoint1(int x,int y),X=x;Y=y;,Tpoint1(Tpoint1,Tpoint1(),coutDestructor calledn;,int Xcoord(),return X;,int Ycoord(),return Y;,private:,int X,Y;,;,Tpoint1:Tpoint1(Tpoint1&p),X=p.X;,Y=p.Y;,coutCopy-initialization Constructor calledn;,例,8-6,分析程序输出结果,熟悉拷贝构造函数的用法。,#include tpoint1.h,Tpoint1 fun(Tpoint1 Q);,void main(),Tpoint1 M(12,20),P(0,0),S(0,0);,Tpoint1 N(M);,P=fun(N);,S=M;,coutP=P.Xcoord(),P.Ycoord()endl;,coutS=S.Xcoord(),S.Ycoord()endl;,例,8-6,分析程序输出结果,熟悉拷贝构造函数的用法。,8.6,常成员,C+,类中的常类型成员称为常成员。常成员分为常数据成员和常成员函数。,一、常数据成员,1,、常数据成员的定义格式:,const,;,2,、常数据成员的特点:,定义的常数据成员要在构造函数中通过成员初始化列表的方式对它初始化;,常数据成员是不能被赋值的,因为常数据成员的值是不能改变的。,37,8.6,常成员,成员初始化列表的格式:,():,class A,public:,A(int i,int j):a(i),b=j;,private:,const int a;,int b;,;,是由若干个初始化项组成,多个初始化项用逗号分隔。,对常数据成员初始化应作为一个成员初始化列表中的一个初始化项。,#include,class MY,public:,MY(int i,int j,int k);,void PrintNumber();,int GetSum(MY m);,private:,int a,b,c;,static int s;,;,int MY:s=0;,MY:MY(int i,int j,int k),a=i;b=j;c=k;,s=a+b+c;,例,8-10,分析程序输出结果,学会常数据成员的用法。,void MY:PrintNumber(),couta,b,cendl;,int MY:GetSum(MY m),return MY:s;,二、常成员函数,常成员函数是指成员函数是常类型说明格式:,(),const,;,const,是函数类型的一部分,在函数说明和函数定义时都要有。,常对象只能调,常成员函数不能调,非,常成员函数,注意:,1,、非,常数据成员在常成员函数中可以引用,但不可以改变。而常数据成员在常成员函数和常成员函数中都不可以改变。,2,、常对象的数据成员都是常数据成员,其值不能改变。但是,常对象的没加修饰符,const,的成员函数,仍然是,非,常成员函数。,37,#include,class MY,public:,MY(int i,int j,int k);,void PrintNumber();,int GetSum(MY m);,private:,int a,b,c;,static int s;,;,int MY:s=0;,MY:MY(int i,int j,int k),a=i;b=j;c=k;,s=a+b+c;,例,8-10,分析程序输出结果,学会常数据成员的用法。,void MY:PrintNumber(),couta,b,cendl;,int MY:GetSum(MY m),return MY:s;,一、指向数据成员的指针,1,、指向类的数据成员的指针的定义和赋值:,:,class A,public:,A(int i),a=i;,int fun(int b),return a*c+b;,int c;,private:,int a;,;,定义一个指向类,A,的数据成员,c,的指针,pc,,采用如下赋初值的格式:,int A:*pc=,采用赋值时定义格式如下:,int A:*pc;,pc=,41,8.7,指向成员的指针,2,、指向数据成员指针的表示,通常指向类的数据成员的指针有两种表示方式,1,st,用一般对象来表示:,.*,2,nd,用指向对象的指针来表示,-*,实例,2,:对象,A,是通过指向它的指针,p,表示,成员,c,是通过指向它的指针,pc,来表示。,int A:*pc;,pc=,实例,1,:已知定义的类,A,成员,c,是通过指向它的指针,pc,来表示,A a,int A:*pc=,a.*pc=8;,/,改变对象,a,的成员,c,的值,42,二、指向成员函数的指针,1,、指向类的成员函数的指针的定义和赋值:,(,:,),(),静态数据成员属于类,而不是属于每个对象,是该类中所有对象所共有的。,定义一个指向类,A,的成员函数,fun(),的指针,pfun,,采用赋初值的格式如下:,int(A:*pfun)(int)=A:fun;,采用赋值时定义格式如下:,int(A:*pfun)(int);,pfun=A:fun;,43,2,、指向类的成员函数指针的表示,通常指向类的成员函数的指针有两种表示方式,1,st,用一般对象来表示:,.*(),2,nd,用指向对象的指针来表示,-*(),实例:,已知定义的类,A,A a;,A*pc=,int(A:*fun)(int)=a:fun,(a.*fun)(10);,(p-*pfun)(10);,44,#include,class A,public:,A(int i),a=i;,int fun(int b),return a*c+b;,int c;,private:,int a;,;,例,A,分析程序输出结果,熟悉指向类的成员的指针的用法。,void main(),A a(15);,int A:*pc;,pc=,a.*pc=2;,int(A:*pfun)(int);,pfun=A:fun;,A*pa=,cout*pfun)(20)endl;,例,A,分析程序输出结果,熟悉指向类的成员的指针的用法。,8.8,友元,类具有封装性,程序中的其它函数无法访问类的私有成员;如想访问必须通过调用该类的公有成员函数来实现。,为了提高效率,引进友元函数,使它可以作为普通函数来直接访问类的所有成员,包括私有成员。,引进友元类使得整个类作为另一个类友元,那么这个类的所有成员都是另一个类的友元函数。,49,一、友元函数,1,、友元函数,(说明在类体内),定义格式,:,firend();,友元函数的说明位置可以放在类体内任何地方,通常放在类体内的开始位置,成员访问权限说明符,public,private,和,protect,通常与友元函数无关。友元函数一般定义在类体外。,2,、友元函数的特点,友元函数是一种说明在类体内的普通函数,它不是成员函数。,友元函数说明它是类的,“,朋友,”,。可以访问该类中的所有成员;包括私有成员和保护成员。,友元函数会破坏数据的隐蔽性,降低面向对象程序设计的价值。使用时应该慎重。,50,二、友元类,友元类是一种友元,它把一个类作为另一个类的友元。,1,、友元类的定义格式:,在一个类中说明另一个类。被说明的类称为该类的友元类。说明友元类的格式:,firend class;,2,、友元类的特点,友元类是另一个类的友元类时,该类的所有成员函数是另一个类的友元函数。,友元类的成员函数可以引用另一个类的私有成员和其他成员。,友元类的关系是不可逆的。,53,
展开阅读全文