《C++程序设计_第7章 类与对象.ppt》由会员分享,可在线阅读,更多相关《C++程序设计_第7章 类与对象.ppt(48页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第第7章章 类与对象(一)类与对象(一)面向对象的基本概念面向对象的基本概念类的定义类的定义创建对象创建对象构造函数与析构函数构造函数与析构函数对象数组对象数组this指针指针静态成员静态成员友元友元类的作用域类的作用域4/8/20231类和对象类和对象面向对象的基本概念面向对象的基本概念*1.面向对象与面向过程的区别面向对象与面向过程的区别:v我要开车去新疆我要开车去新疆v面向过程面向过程我开车,我过陕西,我过兰州我开车,我过陕西,我过兰州v面向对象面向对象我命令车去新疆我命令车去新疆车怎么去我不关心车怎么去我不关心(封装封装)4/8/20232类和对象类和对象2.类类(class)和对象和
2、对象(object)的概念的概念v对象是系统中用来描述客观事务的一个实体,它通对象是系统中用来描述客观事务的一个实体,它通过过“属性属性attribute(数据成员数据成员)”和和“行为行为behavior(成员函数、方法成员函数、方法)”来分别实体的静态属性和动态来分别实体的静态属性和动态属性。属性。v类是具有共同属性和行为的对象的抽象。对象是类类是具有共同属性和行为的对象的抽象。对象是类的实例(的实例(instance)。)。学生学生A抽象抽象类类对象对象学生学生学号学号姓名姓名学习()学习()学生学生A学号学号=101姓名姓名=TOM实例化实例化4/8/20233类和对象类和对象*3.类
3、(对象)之间的关系类(对象)之间的关系n关联关系关联关系教师教师姓名姓名教学(学生教学(学生 A)学生学生学号学号姓名姓名学习()学习()学校学校4/8/20234类和对象类和对象n继承关系继承关系(一般和特殊一般和特殊)xx是一种是一种XX类的继承层次类的继承层次4/8/20235类和对象类和对象n聚合关系(整体和部分)聚合关系(整体和部分)队长队长 队员队员 球队球队聚集聚集头头 身体身体人人组合组合4/8/20236类和对象类和对象多态多态车车go()大卡车大卡车go()小汽车小汽车go()4/8/20237类和对象类和对象面向对象的设计思想面向对象的设计思想n有那些类(对象)有那些类(
4、对象)?n每一种类(对象)有哪些属性和方法?每一种类(对象)有哪些属性和方法?n类(对象)之间有哪些关系?类(对象)之间有哪些关系?4/8/20238类和对象类和对象类的定义类的定义格式一般分为说明部分和实现部分。说明部分:是用来说明类中的成员,包含数据成员的说明和成员函数的说明。成员函数是用来对数据成员进行操作的,也称为“方法”。实现部分:是用来对成员函数进行定义。4/8/20239类和对象类和对象说明部分的一般格式class 类类型名类类型名 public:公有成员说明公有成员说明 private:私有成员说明私有成员说明;私有访问权限,为默认值,可缺省公有访问权限除本类中的成员函数及友元
5、外,其他类外函数不能访问。程序中的任何函数都可访问4/8/202310类和对象类和对象例如:定义一个PersonPerson类,设PersonPerson具有的特征:属性(姓名、年龄、性别),方法(输出一个人的属性);则对应着有4个成员:三个数据成员,一个成员函数。三个数据成员定义为私有成员,print成员函数定义为公有成员。则有:class CPersonclass CPerson public:public:void print();void print();private:private:char name10;char name10;int int age;age;char sex;c
6、har sex;类名通常用C字母开始,以区别其他标识符4/8/202311类和对象类和对象类的类的实现部分实现部分类的实现部分即定义它的成员函数,如在类说明内部定义,则方式与定义普通函数大体相同。若在类说明外部定义成员函数,则应使用类域运算符:(p21)指明该函数是哪个类中的成员函数。格式为:函数类型函数类型 类名类名:成员函数名(形参表)成员函数名(形参表)函数体函数体;void CPerson:print()void CPerson:print()coutcoutnameagesexnameagesex endl endl;l除特殊指明外,成员函数操作的是同一对象中的数据成员。l不同的类允
7、许有相同名称的成员函数,因此,在类外定义成员函数的实现时,必须在成员函数名前加上所属类名和作用域操作符“:”。4/8/202312类和对象类和对象当当成成员员函函数数的的规规模模较较小小时时,可可在在在在类类类类中中中中定定定定义义义义成成成成员员员员函函函函数数数数,成成成成为内联成员函数为内联成员函数为内联成员函数为内联成员函数。例:。例:class CDate public:void setDate(int m,int d,int y)/置日期值 month=m;day=d;year=y;void print();private:int month,day,year;void CDate
8、:print()CDate:print()cout coutyear.month.dayyear.month.day-数据成员数据成员 或或 指针名指针名-成员函数成员函数n(*(*指针名指针名).).数据成员数据成员 或或(*(*指针名指针名).).成员函数成员函数例:例:pDatepDate-day=30;-day=30;pDatepDate-Print();-Print();(*(*pDatepDate).day=30;(*).day=30;(*pDatepDate).Print();).Print();用引用访问对象成员用引用访问对象成员:引用引用名名.数据成员数据成员 或或 引用引用
9、名名.成员函数成员函数例:例:rDate.year=2008;rDate.Print();rDate.year=2008;rDate.Print();4/8/202316类和对象类和对象注意:在成员函数中访问成员无须加对象名来作为前缀。如:void CDateCDate:print():print()cout coutyear.month.dayyear.month.day endl endl;在yearyear等成员之前不能加对象名,在定义类时,成员函数是所有对象共享的代码,不被某一个对象独占。也无法确定类的对象名。注注 意意4/8/202317类和对象类和对象例 一个完整的程序/CDate
10、.hclass CDate public:void setDate(int m,int d,int y)/置日期值 month=m;day=d;year=y;void print();private:int month,day,year;void CDate:print()coutyear.month.day endl;4/8/202318类和对象类和对象续例 一个完整的程序#include#include CDate.hvoid main()CDate date1;date1.setDate(8,5,1996);date1.print();/coutdate1.yearprint();*/t
11、estClasstestCDate.cpp4/8/202319类和对象类和对象类的类的成员函数成员函数v内联函数:指定义在类体内的成员函数。v外联函数:指说明在类体内,定义在类体外的成员函数。类外定义的函数缺省情况下都是外联函数,用关键字 inline 可以强制转换。对于内联成员函数,编译时在所有调用该函数的地方将对于内联成员函数,编译时在所有调用该函数的地方将装入装入实际的函数代码。实际的函数代码。1.1.1.1.内联函数和外联函数内联函数和外联函数内联函数和外联函数内联函数和外联函数4/8/202320类和对象类和对象class CDate public:void setDate(int
12、m,int d,int y)/内联函数之一内联函数之一 month=m;day=d;year=y;void print();private:int month,day,year;inline void CDate:print()/内联函数之二内联函数之二 coutyear.month.day endl;4/8/202321类和对象类和对象2.2.2.2.设置参数的缺省值设置参数的缺省值函数在定义时可以预先定义出形参的缺省值。调用时如果给出实参,则用实参初始化形参,如果没有给出实参,则采用预先定义形参的缺省值。例如:void setDate(int m,int d28,int y2008);/缺
13、省参数按缺省参数按从右往左从右往左的方式的方式或或void setDate(int m,int d28,int y2008)在进行函数调用时,主调函数的实参与被调函数的形参在进行函数调用时,主调函数的实参与被调函数的形参按按从左到右从左到右的位置结合。的位置结合。TestParaDefault.cpp4/8/202322类和对象类和对象3.3.3.3.函数的重载函数的重载 函数的重载函数的重载:出现在相同作用域的两个函数,如果具出现在相同作用域的两个函数,如果具有相同的名字而形参表不同,则称为重载函数有相同的名字而形参表不同,则称为重载函数(overloaded functionoverloa
14、ded function)。)。调用时,会根据不同的参数调用时,会根据不同的参数表选择对应的成员函数。表选择对应的成员函数。重重载载函函数数,必必须须:函函数数名名相相同同,函函数数的的作作用用域域相相同同,函数的参数个数或参数类型不同。函数的参数个数或参数类型不同。使用重载函数时应注意:只有返回值不同,不能成为重载函数。int max(int a,int b);double max(int a,int b);/错误 使用带缺省值的函数时,可能引发错误。如:int max(int a,int b=0);int max(int c);当用一个实参调用该函数时,如max(2),则会出现调用歧义性4
15、/8/202323类和对象类和对象构造函数和析构函数构构造造函函数数和和析析构构函函数数都都是是类类的的成成员员函函数数,是是特特殊殊的成员函数,不能被调用而由系统自动调用的成员函数,不能被调用而由系统自动调用/执行。执行。构构造造函函数数名名与与类类名名相相同同;析析构构函函数数名名为为类类名名前前加加“”。构构造造函函数数的的功功能能是是在在创创建建对对象象时时给给对对象象分分配配内内存存空间空间 ,并可使用给定值来,并可使用给定值来初始化初始化对象。对象。析析构构函函数数的的功功能能是是用用来来释释放放一一个个对对象象的的已已分分配配空空间。并可在对象被清除前,完成一些间。并可在对象被清
16、除前,完成一些清理清理工作。工作。4/8/202324类和对象类和对象对对前前面面的的日日期期类类进进行行修修改改,并并将将定定义义存存放放在在CDate1.hCDate1.h文件中。文件中。如:如:classclass CDate1 CDate1 public:public:CDate1(CDate1(int int y,y,intint m,m,intint d);d);CDate1();CDate1();void print();void print();private:private:intint year,month,day;year,month,day;函数名与类名一致,无类型但可
17、有参数名字与类名一致,前有,无类型无参数4/8/202325类和对象类和对象CDate1:CDate1(CDate1:CDate1(int int m,m,intint d,d,intint y)y)month=m;month=m;day=d;day=d;year=y;year=y;coutcoutConstructor called.n;Constructor called.n;CDate1:CDate1()CDate1:CDate1()coutcoutDestructor called.n;Destructor called.n;void CDate1:print()void CDate1
18、:print()cout coutyear.month.dayyear.month.dayendlendl;与其他成员函数定义一样,两种函数的定义可放在类体内,也可放在类体外4/8/202326类和对象类和对象#include include.h#include CDate1.h#include CDate1.hvoid main()void main()CDate1 CDate1 today(2007,4,1),tomorrow(today(2007,4,1),tomorrow(2007,4,22007,4,2););coutcouttoday is;today is;today.print
19、();today.print();coutcouttomorrow is;tomorrow is;tomorrow.print();tomorrow.print();执行程序后,输出结果为:执行程序后,输出结果为:执行程序后,输出结果为:执行程序后,输出结果为:函数结束时,自动调用析构Constructor Called.Constructor Called.today is 2007.4.1tomorrow is 2007.4.2Destructor called.Destructor called.4/8/202327类和对象类和对象构造函数构造函数构造函数构造函数的的特点特点有:有:程程
20、序序中中一一般般不不直直接接调调用用构构造造函函数数,在在创创建建对对象象时时系系统统自自动动调用调用构造函数。构造函数。构造函数构造函数可以重载可以重载,即可定义多个参数个数不同的函数,即可定义多个参数个数不同的函数构造函数有构造函数有隐含的返回值隐含的返回值,并由系统内部使用,并由系统内部使用析构函数析构函数析构函数析构函数的的特点特点有:有:一个类中只能定义一个析构函数,即一个类中只能定义一个析构函数,即不能重载不能重载析构函数可以被调用,也可系统调用析构函数可以被调用,也可系统调用被自动调用的情况有两种:被自动调用的情况有两种:在一个函数体内定义的一个对象,当在一个函数体内定义的一个对
21、象,当函数结束函数结束时时用用newnewnewnew运算符动态创建的一个对象,在运算符动态创建的一个对象,在使用使用deletedelete释放释放时时4/8/202328类和对象类和对象缺省构造函数和缺省析构函数缺省构造函数和缺省析构函数在类定义中可以不定义任何构造函数,这时编译器在类定义中可以不定义任何构造函数,这时编译器会自动生成一个不带参数的缺省构造函数。会自动生成一个不带参数的缺省构造函数。其格式为:其格式为:()()则则在程序中定义一个对象而未指明初始化时,在程序中定义一个对象而未指明初始化时,编编译译器器便便按按缺缺省省构构造造函函数数来来初初始始化化该该对对象象。若定义了构造
22、函数,则编译器就不会再生成缺省构造函数,必须使用定义的构造函数创建对象。同同理理,若若一一个个类类中中未未定定义义析析构构函函数数,编编译译系系统统也也生生成一个缺省析构函数。成一个缺省析构函数。其格式为:其格式为:()()这也是前面的程序中可以没有构造和析构函数的原因4/8/202329类和对象类和对象class CConstruct public:CConstruct(int x,int y);CConstruct();void print();private:int m1,m2;CConstruct:CConstruct(int x,int y)m1=x;m2=y;CConstruct:
23、CConstruct()m1=0;m2=0;TestConsOverLoad.cpp例:例:4/8/202330类和对象类和对象void CConstruct:print()coutm1,m2endl;void main()CConstruct c2;CConstruct c1(3,4);c1.print();不带参数创建对象,调用无参构造函数4/8/202331类和对象类和对象拷贝初始化构造函数拷贝初始化构造函数构造函数除可以用基本数据类型初始化对象外,还可以使用已存在的同类型的对象即类类型的对象来初始化正在创建的对象。为此,必须在类中定义一个特殊的构造函数来完成这个工作,这个构造函数被称为
24、拷贝初始化构造函数。格式为::(&)如如:student:student(student student:student(student&s)s)每个类中必须有一个。若类中未说明,则编译系统会自动生成缺省函数。4/8/202332类和对象类和对象class CMyClasspublic:CMyClass(int x);CMyClass(CMyClass&c);private:int member;CMyClass:CMyClass(int x)member=x;CMyClass:CMyClass(CMyClass&c)coutcopy constructor calledprint()test
25、ObjectArray.cpp4/8/202337类和对象类和对象每一个类的每一个类的非静态成员函数非静态成员函数非静态成员函数非静态成员函数中的都有一个指针形参中的都有一个指针形参this,this,用于指向正在操作该成员函数的对象。例如:用于指向正在操作该成员函数的对象。例如:class CDate3class CDate3 public:public:CDate3(CDate3(intint y,y,intint m,m,intint d);d);void print(CDate3*t);void print(CDate3*t);void print();void print();pri
26、vate:private:intint year,month,day;year,month,day;CDate3:CDate3(CDate3:CDate3(intint y,y,intint m,m,intint d)d)year=y;month=m;year=y;month=m;day=d;day=d;thisthis指针指针testThis.cpp4/8/202338类和对象类和对象void void CDate3CDate3:print(:print(CDate3CDate3*t)*t)cout coutyear.month.dayyear.month.dayendlendl;voidv
27、oid CDate3 CDate3:print():print()cout coutyear.month.this-year.month.daydayendlendl;#include#include.h#include#include CDate3CDate3.h.hvoid main()void main()CDate3 objThisCDate3 objThis(2008,4,23);(2008,4,23);objThis objThis.print(&.print(&objThisobjThis););objThis objThis.print();.print();隐含的指针隐含的指
28、针形参形参this4/8/202339类和对象类和对象静态成员静态成员定义类时,可用关键字static声明的数据成员或成员函数声明的数据成员或成员函数称为静态成员静态成员,包括静态数据成员和静态成员函数静态数据成员和静态成员函数。静态数据成员数据成员是在编译时被创建,与对象是否存在无关,其内存空间为数据区,其生命期一直到程序结束。静态数据成员必须在数据成员必须在类外类外初始化:初始化:数据类型 类名:成员名=初始值;静态成员函数属于类,而不是对象成员静态成员函数属于类,而不是对象成员(无无thisthis指针用来存指针用来存放对象的地址)放对象的地址),不能,不能直接直接引用具体对象中的引用具
29、体对象中的非静态成员非静态成员。须使用须使用 (对象名对象名.成员名成员名)来引用。)来引用。可以通过对象名或类名来访问静态成员。可以通过对象名或类名来访问静态成员。4/8/202340类和对象类和对象静态数据成员静态数据成员#include class CCat public:static int count;CCat(int color)count+;colorFur=color;private:int colorFur;int CCat:count=0;void main()CCat mm(0);CCat pp(1);coutCCat:countendl;coutmm.countendl
30、;CCat:count+4/8/202341类和对象类和对象静态成员函数静态成员函数class Mclass M public:public:M(M(intint a)A=a;a)A=a;staticstatic void f1(M m);void f1(M m);private:private:int int A;A;staticstatic int int B;B;intint M:B=0;M:B=0;void void M:f1(M m)M:f1(M m)coutcoutm.Am.AB Bendlendl;void main()void main()M p(5);M p(5);M:f1(
31、p)M:f1(p);/p.f1(p);/p.f1(p);静态成员声明静态成员定义引用非静态成员引用静态成员函数testStaticFunction.cpp4/8/202342类和对象类和对象友元函数友元函数在在某某个个类类定定义义中中用用friendfriendfriendfriend说说明明一一个个外外部部函函数数后后,这这个个外外部部函函数数就就可可直直接接访访问问该该类类的的任任何何私私有有成成员员。则则该该外部函数称为这个类的友元函数。外部函数称为这个类的友元函数。采采用用友友元元的的目目的的主主要要是是为为提提高高效效率率。显显然然它它破破坏坏了类的封装性了类的封装性。注意:注意:在
32、在某某个个类类中中说说明明的的友友元元函函数数并并不不是是该该类类的的成成员员函函数数。它它可可以以是是外外部部的的一一个个独独立立函函数数,也也可可以以是是另另外外一一个类中的成员函数。个类中的成员函数。4/8/202343类和对象类和对象class class CFriendCFriend friend friend void gFunc1(void gFunc1(CFriendCFriend&p);&p);/声明友元函数声明友元函数 private:private:void func1()void func1()cout coutfriendn;friendn;友元为外部的独立函数voi
33、d gFunc1(void gFunc1(CFriendCFriend&p&p)/定义外部友元函数,使用定义外部友元函数,使用类对象引用作参数类对象引用作参数/注:不是成员函数注:不是成员函数不加类名不加类名:p.func1(p.func1();/友友元元的的使使用用,调调用用私私有有成成员员testFriendFunction.cpp4/8/202344类和对象类和对象class CFriendB;class CFriendA public:int f1(CFriendB&b);/类中使用另一个类对象须先有其说明 int f2(CFriendB&b);class CFriendB frien
34、d int CFriendA:f1(CFriendB&b);/把CFriendA中f1说明为友元 private:static int m;int CFriendB:m=5;int CFriendA:f1(CFriendB&b)return b.m;/正确:int CFriendA:f2(CFriendB&b)return b.m;/错误:友元为另一个类的成员函数testFriendFunction2.cpp4/8/202345类和对象类和对象同函数一样,类也可以声明为另一个类的友元,称同函数一样,类也可以声明为另一个类的友元,称为友元类。为友元类。若若A为为B的友元类,则的友元类,则A类的所
35、有成员函数都是类的所有成员函数都是B类类的友元函数,都可以访问的友元函数,都可以访问B类的私有和保护成员。类的私有和保护成员。声明的形式为声明的形式为:class Bfriend class A;注意注意:1)友元关系是不能传递的。)友元关系是不能传递的。2)友元关系是是单向的。)友元关系是是单向的。友元类友元类testFriendClass.cpp4/8/202346类和对象类和对象类的作用域类的作用域类类的的作作用用域域(简简称称类类域域)是是指指类类的的定定义义中中由由一一对对花花括括号号括括起起的的部部分分。类类的的所所有有成成员员都都在在类类的的作作用用域域中中。类类域域区区分分符符
36、“:”来确定成员函数的类域,从而可在类外定义成员函数。来确定成员函数的类域,从而可在类外定义成员函数。同同变变量量一一样样,在在类类定定义义体体和和函函数数体体外外定定义义的的对对象象为为全全局局对对象象,而而在在类类定定义义体体内内或或在在函函数数体体内内定定义义的的对对象象为为局局部部对对象象。全全局局对对象象的的作作用用域域是是从从定定义义它它的的位位置置开开始始直直至至文文件件的的结结束束,而而局局部对象的作用域只在类作用域或函数体内。部对象的作用域只在类作用域或函数体内。4/8/202347类和对象类和对象#include int pp=0;class CScope public:int pp;void rp(int pp);void CScope:rp(int pp):pp=11;/变量名前加域区分符给全局变量变量名前加域区分符给全局变量pp赋值赋值 this-pp=100;/给数据成员赋值给数据成员赋值 coutppendl;void main()CScope a;a.rp(4);coutppna.ppendl;testScope.cpp4/8/202348类和对象类和对象