1、12023-2-11类和对象类和对象第第7章章 类与对象(一)类与对象(一)面向对象的基本概念面向对象的基本概念类的定义类的定义创建对象创建对象构造函数与析构函数构造函数与析构函数对象数组对象数组this指针指针静态成员静态成员友元友元类的作用域类的作用域22023-2-11类和对象类和对象面向对象的基本概念面向对象的基本概念*1.面向对象与面向过程的区别面向对象与面向过程的区别:v我要开车去新疆我要开车去新疆v 面向过程面向过程 我开车,我过陕西,我过兰州我开车,我过陕西,我过兰州v 面向对象面向对象 我命令车去新疆我命令车去新疆 车怎么去我不关心车怎么去我不关心(封装封装)32023-2-
2、11类和对象类和对象2.类类(class)和对象和对象(object)的概念的概念v对象是系统中用来描述客观事务的一个实体,它通对象是系统中用来描述客观事务的一个实体,它通过过“属性属性attribute(数据成员数据成员)”和和“行为行为behavior(成员函数、方法成员函数、方法)”来分别实体的静态属性和动态属来分别实体的静态属性和动态属性。性。v类是具有共同属性和行为的对象的抽象。对象是类类是具有共同属性和行为的对象的抽象。对象是类的实例(的实例(instance)。)。学生学生A抽象抽象类类对象对象学生学生学号学号姓名姓名学习()学习()学生学生A学号学号=101姓名姓名=TOM实例
3、化实例化42023-2-11类和对象类和对象*3.类(对象)之间的关系类(对象)之间的关系n关联关系关联关系教师教师姓名姓名教学(学生教学(学生 A)学生学生学号学号姓名姓名学习()学习()学校学校52023-2-11类和对象类和对象n继承关系继承关系(一般和特殊一般和特殊)xx是一种是一种XX类的继承层次类的继承层次62023-2-11类和对象类和对象n聚合关系(整体和部分)聚合关系(整体和部分)队长队长 队员队员 球队球队聚集聚集头头 身体身体人人组合组合72023-2-11类和对象类和对象多态多态车车go()大卡车大卡车go()小汽车小汽车go()82023-2-11类和对象类和对象面向
4、对象的设计思想面向对象的设计思想n有那些类(对象)有那些类(对象)?n每一种类(对象)有哪些属性和方法?每一种类(对象)有哪些属性和方法?n类(对象)之间有哪些关系?类(对象)之间有哪些关系?92023-2-11类和对象类和对象类的定义类的定义格式一般分为说明部分和实现部分。说明部分:是用来说明类中的成员,包含数据成员的说明和成员函数的说明。成员函数是用来对数据成员进行操作的,也称为“方法”。实现部分:是用来对成员函数进行定义。102023-2-11类和对象类和对象说明部分的一般格式class 类类型名类类型名 public:公有成员说明公有成员说明 private:私有成员说明私有成员说明;
5、私有访问权限,为默认值,可缺省公有访问权限除本类中的成员函数及友元外,其他类外函数不能访问。程序中的任何函数都可访问112023-2-11类和对象类和对象例如:定义一个PersonPerson类,设PersonPerson具有的特征:属性(姓名、年龄、性别),方法(输出一个人的属性);则对应着有4个成员:三个数据成员,一个成员函数。三个数据成员定义为私有成员,print成员函数定义为公有成员。则有:class CPersonclass CPerson public:public:void print();void print();private:private:char name10;char
6、 name10;int int age;age;char sex;char sex;类名通常用C字母开始,以区别其他标识符122023-2-11类和对象类和对象类的实现部分类的实现部分类的实现部分即定义它的成员函数,如在类说明内部定义,则方式与定义普通函数大体相同。若在类说明外部定义成员函数,则应使用类域运算符:(p21)指明该函数是哪个类中的成员函数。格式为:函数类型函数类型 类名类名:成员函数名(形参表)成员函数名(形参表)函数体函数体;void CPerson:print()void CPerson:print()coutnameagesex endl coutnameagesex en
7、dl;l除特殊指明外,成员函数操作的是同一对象中的数据成员。l不同的类允许有相同名称的成员函数,因此,在类外定义成员函数的实现时,必须在成员函数名前加上所属类名和作用域操作符“:”。132023-2-11类和对象类和对象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:print()CDate:print()coutyear.month.day endl coutyear.month.day
8、-数据成员数据成员 或或 指针名指针名-成员函数成员函数n(*指针名指针名).).数据成员数据成员 或或 (*指针名指针名).).成员函数成员函数例:例:pDate-day=30;pDatepDate-day=30;pDate-Print();-Print();(*pDate).day=30;(pDate).day=30;(*pDatepDate).Print();).Print();用引用访问对象成员用引用访问对象成员:引用引用名名.数据成员数据成员 或或 引用引用名名.成员函数成员函数例:例:rDate.year=2008;rDate.Print();rDate.year=2008;rDa
9、te.Print();172023-2-11类和对象类和对象注意:在成员函数中访问成员无须加对象名来作为前缀。如:void CDateCDate:print():print()coutyear.month.day endl coutyear.month.day endl;在yearyear等成员之前不能加对象名,在定义类时,成员函数是所有对象共享的代码,不被某一个对象独占。也无法确定类的对象名。注注 意意182023-2-11类和对象类和对象例 一个完整的程序/CDate.hclass CDate public:void setDate(int m,int d,int y)/置日期值 mont
10、h=m;day=d;year=y;void print();private:int month,day,year;void CDate:print()coutyear.month.day endl;192023-2-11类和对象类和对象续例 一个完整的程序#include#include CDate.hvoid main()CDate date1;date1.setDate(8,5,1996);date1.print();/coutdate1.yearprint();*/testClasstestCDate.cpp202023-2-11类和对象类和对象类的成员函数类的成员函数v内联函数:指定义
11、在类体内的成员函数。v外联函数:指说明在类体内,定义在类体外的成员函数。类外定义的函数缺省情况下都是外联函数,用关键字 inline 可以强制转换。对于内联成员函数,编译时在所有调用该函数的地方将对于内联成员函数,编译时在所有调用该函数的地方将装入装入实际的函数代码。实际的函数代码。212023-2-11类和对象类和对象class CDate public:void setDate(int m,int d,int y)/month=m;day=d;year=y;void print();private:int month,day,year;inline void CDate:print()/c
12、outyear.month.day endl;222023-2-11类和对象类和对象函数在定义时可以预先定义出形参的缺省值。调用时如果给出实参,则用实参初始化形参,如果没有给出实参,则采用预先定义形参的缺省值。例如:void setDate(int m,int d28,int y2008);/缺省参数按缺省参数按从右往左从右往左的方式的方式或或void setDate(int m,int d28,int y2008)在进行函数调用时,主调函数的实参与被调函数的形参在进行函数调用时,主调函数的实参与被调函数的形参按按从左到右从左到右的位置结合。的位置结合。TestParaDefault.cpp2
13、32023-2-11类和对象类和对象 函数的重载函数的重载:出现在相同作用域的两个函数,如果具出现在相同作用域的两个函数,如果具有相同的名字而形参表不同,则称为重载函数(有相同的名字而形参表不同,则称为重载函数(overloaded functionoverloaded function)。调用时,会根据不同的参数表)。调用时,会根据不同的参数表选择对应的成员函数。选择对应的成员函数。重载函数,必须重载函数,必须:函数名相同,函数的作用域相同,:函数名相同,函数的作用域相同,函数的参数个数或参数类型不同。函数的参数个数或参数类型不同。使用重载函数时应注意:只有返回值不同,不能成为重载函数。in
14、t max(int a,int b);double max(int a,int b);/错误 使用带缺省值的函数时,可能引发错误。如:int max(int a,int b=0);int max(int c);当用一个实参调用该函数时,如max(2),则会出现调用歧义性242023-2-11类和对象类和对象构造函数和析构函数构造函数和析构函数都是类的成员函数,是特殊构造函数和析构函数都是类的成员函数,是特殊的成员函数,不能被调用而由系统自动调用的成员函数,不能被调用而由系统自动调用/执行。执行。构造函数名与类名相同;析构函数名为类名前加构造函数名与类名相同;析构函数名为类名前加“”。构造函数构
15、造函数的功能是在创建对象时给对象的功能是在创建对象时给对象分配分配内存内存空间空间 ,并可使用给定值来,并可使用给定值来初始化初始化对象。对象。析构函数析构函数的功能是用来的功能是用来释放释放一个对象的已分配空一个对象的已分配空间。并可在对象被清除前,完成一些间。并可在对象被清除前,完成一些清理清理工作。工作。252023-2-11类和对象类和对象函数名与类名一致,无类型但可有参数名字与类名一致,前有,无类型无参数262023-2-11类和对象类和对象与其他成员函数定义一样,两种函数的定义可放在类体内,也可放在类体外272023-2-11类和对象类和对象函数结束时,自动调用析构Construc
16、tor Called.Constructor Called.today is 2007.4.1tomorrow is 2007.4.2Destructor called.Destructor called.282023-2-11类和对象类和对象292023-2-11类和对象类和对象若定义了构造函数,则编译器就不会再生成缺省构造函数,必须使用定义的构造函数创建对象。这也是前面的程序中可以没有构造和析构函数的原因302023-2-11类和对象类和对象class CConstruct public:CConstruct(int x,int y);CConstruct();void print();p
17、rivate:int m1,m2;CConstruct:CConstruct(int x,int y)m1=x;m2=y;CConstruct:CConstruct()m1=0;m2=0;TestConsOverLoad.cpp例:例:312023-2-11类和对象类和对象void CConstruct:print()coutm1,m2endl;void main()CConstruct c2;CConstruct c1(3,4);c1.print();不带参数创建对象,调用无参构造函数322023-2-11类和对象类和对象构造函数除可以用基本数据类型初始化对象外,还可以使用已存在的同类型的对
18、象即类类型的对象来初始化正在创建的对象。为此,必须在类中定义一个特殊的构造函数来完成这个工作,这个构造函数被称为拷贝初始化构造函数。格式为::(&):student:student(student student:student(student&s)s)每个类中必须有一个。若类中未说明,则编译系统会自动生成缺省函数。332023-2-11类和对象类和对象class CMyClasspublic:CMyClass(int x);CMyClass(CMyClass&c);private:int member;CMyClass:CMyClass(int x)member=x;CMyClass:CMy
19、Class(CMyClass&c)coutcopy constructor calledprint()testObjectArray.cpp382023-2-11类和对象类和对象testThis.cpp392023-2-11类和对象类和对象隐含的指针隐含的指针形参形参this402023-2-11类和对象类和对象定义类时,可用关键字static声明的数据成员或成员函数声明的数据成员或成员函数称为静态成员静态成员,包括静态数据成员和静态成员函数静态数据成员和静态成员函数。静态数据成员数据成员是在编译时被创建,与对象是否存在无关,其内存空间为数据区,其生命期一直到程序结束。静态数据成员必须在数据成
20、员必须在类外类外初始化:初始化:数据类型 类名:成员名=初始值;静态成员函数属于类,而不是对象成员静态成员函数属于类,而不是对象成员(412023-2-11类和对象类和对象静态数据成员静态数据成员#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;CCat:count+422
21、023-2-11类和对象类和对象静态成员函数静态成员函数静态成员声明静态成员定义引用非静态成员引用静态成员函数testStaticFunction.cpp432023-2-11类和对象类和对象442023-2-11类和对象类和对象友元为外部的独立函数testFriendFunction.cpp452023-2-11类和对象类和对象class CFriendB;class CFriendA public:int f1(CFriendB&b);/类中使用另一个类对象须先有其说明 int f2(CFriendB&b);class CFriendB friend int CFriendA:f1(CFr
22、iendB&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.cpp462023-2-11类和对象类和对象同函数一样,类也可以声明为另一个类的友元,同函数一样,类也可以声明为另一个类的友元,称为友元类。称为友元类。若若A为为B的友元类,则的友元类,则A类的所有成员函数都是类的所有成员函数都是B类类
23、的友元函数,都可以访问的友元函数,都可以访问B类的私有和保护成员。类的私有和保护成员。声明的形式为声明的形式为:class Bfriend class A;注意注意:1)友元关系是不能传递的。)友元关系是不能传递的。2)友元关系是是单向的。)友元关系是是单向的。testFriendClass.cpp472023-2-11类和对象类和对象类的作用域(简称类域)是指类的定义中由一对花括号括类的作用域(简称类域)是指类的定义中由一对花括号括起的部分。类的所有成员都在类的作用域中。类域区分符起的部分。类的所有成员都在类的作用域中。类域区分符“:”来确定成员函数的类域,从而可在类外定义成员函数。来确定成
24、员函数的类域,从而可在类外定义成员函数。同变量一样,在类定义体和函数体外定义的对象为全局对同变量一样,在类定义体和函数体外定义的对象为全局对象,而在类定义体内或在函数体内定义的对象为局部对象。全象,而在类定义体内或在函数体内定义的对象为局部对象。全局对象的作用域是从定义它的位置开始直至文件的结束,而局局对象的作用域是从定义它的位置开始直至文件的结束,而局部对象的作用域只在类作用域或函数体内。部对象的作用域只在类作用域或函数体内。482023-2-11类和对象类和对象#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.cpp