C++面向对象程序设计(第三章).ppt

上传人:夺命阿水 文档编号:236188 上传时间:2023-03-10 格式:PPT 页数:84 大小:721.50KB
返回 下载 相关 举报
C++面向对象程序设计(第三章).ppt_第1页
第1页 / 共84页
C++面向对象程序设计(第三章).ppt_第2页
第2页 / 共84页
C++面向对象程序设计(第三章).ppt_第3页
第3页 / 共84页
C++面向对象程序设计(第三章).ppt_第4页
第4页 / 共84页
C++面向对象程序设计(第三章).ppt_第5页
第5页 / 共84页
点击查看更多>>
资源描述

《C++面向对象程序设计(第三章).ppt》由会员分享,可在线阅读,更多相关《C++面向对象程序设计(第三章).ppt(84页珍藏版)》请在课桌文档上搜索。

1、+程序设计,第三章,第3章 关于类和对象的进一步讨论,3.1构造函数 3.2析构函数 3.3调用构造函数和析构函数的顺序3.4对象数组 3.5对象指针 3.6共用数据的保护(难点)3.7对象的动态建立和释放 3.8对象的赋值和复制 3.9静态成员 3.10友元 3.11类模板,3.1构造函数,3.1.1 对象的初始化3.1.2 构造函数的作用3.1.3 带参数的构造函数3.1.4 用参数初始化表初始化数据成员3.1.5 构造函数的重载3.1.6 使用默认参数的构造函数,确定对象的初始状态,3.1.2构造函数的作用,构造函数的作用:用于为对象分配空间和进行初始化。构造函数的特点:(1)构造函数的

2、名字与它的类名必须相同;(2)它没有类型,不返回值,为public类型;(3)它可以带参数,也可以不带参数;(4)不需要写调用语句,在系统建立对象时由系统自觉调用执行。(5)如果用户没有定义构造函数,C+系统会自动生成一个空的构造函数。(6)允许为内联、重载、带缺省形参的函数。,#include using namespace std;class Time public:Time()hour=0;minute=0;sec=0;void set_time();void show_time();private:int hour;int minute;int sec;,例3.1在例2.3的基础上定义

3、构造成员函数,构造函数,int main()Time t1;/定义对象的同时调用了构造函数 t1.set_time();t1.show_time();Time t2;/定义对象的同时调用了构造函数 t2.show_time();return 0;,void Time:set_time()cinhour;cinminute;cinsec;void Time:show_time()couthour:minute:secendl;,说明,在类Time中定义了构造函数Time,它与所在的类同名。在建立对象时自动执行构造函数,该函数的作用是为对象中的各个数据成员赋初值 0。注意只有执行构造函数时才为数据

4、成员赋初值。程序运行时首先建立对象t1,并对t1中的数据成员赋初值0,然后执行t1.set_time函数,从键盘输入新值给对象t1的数据成员,再输出t1的数据成员的值。接着建立对象t2,同时对t2中的数据成员赋初值0,最后输出t2的数据成员的初值。,10 25 5410:25:54/输出t1的值 0:0:0/输出t2的值也可以在类内声明构造函数,然后在类外定义构造函数。将程序修改为:Time();然后在类外定义构造函数:Time:Time()hour=0;minute=0;sec=0;,/不带参数的构造函数,程序运行的情况为:,3.1.3 带形参数的构造函数,优点:实现不同对象的初始化。一般格

5、式:构造函数名(类型 形参1,类型 形参2,)定义对象的格式:类名 对象名(实参1,实参2,);,例3.2,有两个长方柱,其长、宽、高分别为:(1)12,25,30(2)15,30,21编写程序,在类中用带参数的构造函数,计算它们的体积。分析:可以在类中定义一个计算长方体体积的成员函数计算对象的体积。,#include using namespace std;class Box public:Box(int,int,int);/带形参的构造函数 int volume();private:int height;int width;int length;,Box:Box(int h,int w,i

6、nt len)/长方体构造函数 height=h;width=w;length=len;int Box:volume()/计算长方体的体积 return(height*width*length);,例3.2,当类中无构造函数时,编译系统自动生成一个缺省构造函数,但它不会给类的数据成员初始值。,int main()Box box1(12,25,30);/定义对象box1 cout box1体积=box1.volume()endl;Box box2(15,30,21);/定义对象box2 cout box2体积=box2.volume()endl;return 0;,例3.2,构造函数Box有3个

7、参数,分别代表长、宽、高。在主函数中定义对象box1时,指定了实参12,25,30。然后调用成员函数计算长方体的体积。程序运行的结果如下:box1体积=9000 box2体积=9450 提醒:(1)带形参的构造函数在定义对象时必须指定实参(2)用这种方法可以实现不同对象的初始化。,说明,3.1.4用参数初始化表对数据成员初始化,构造函数的另一种数据初始化写法:利用参数初始化表的方法在函数的首部就能实现数据成员初始化。格式:函数名(类型1 形参1,类型2 形参2):成员名1(形参1),成员名2(形参2)功能:执行构造函数时,将形参1的值赋予成员1,将形参2的值赋予成员2,形参的值由定义对象时的实

8、参值决定。定义对象的格式依然是:类名 对象名(实参1,实参2);,例:定义带形参初始化表的构造函数,Box:Box(int h,int w,int len):height(h),width(w),length(len)定义对象:Box box1(12,25,30);Box box2(15,30,21);,3.1.5构造函数的重载,例3.3:在例3.2的基础上定义两个构造函数其中一个无参数,另一个有参数。,#include using namespace std;class Box public:Box();/不带形参的构造函数为系统默认函数 Box(int h,int w,int len):h

9、eight(h),width(w),length(len)int volume();private:int height;int width;int length;,这是什么?构造函数也可以重载。一个类可以有多个同名构造函数,函数参数的个数、参数的类型各不相同定义对象是只执行一个构造函数,Box:Box()height=10;width=10;length=10;int Box:volume()return(height*width*length);,int main()Box box1;/执行第一个构造函数 coutbox1 体积=box1.volume()endl;Box box2(15,

10、30,25);/执行第二个 构造函数 coutbox2 体积=box2.volume()endl;return 0;,说明,例子中定义了两个构造函数,一个无参数另一个带三个参数。系统根据定义对象的格式决定调用哪个构造函数。对象box1没有实参系统为它调用无参数的构造函数;对象box2带三个实参系统为它调用带形参的构造函数。,3.1.6使用默认参数值的构造函数,C+允许在构造函数里为形参指定默认值,如果创建对象时,未给出相应的实参时,系统将用形参的默认值为形参赋值。格式:函数名(类型 形参1=常数,类型 形参2=常数,);注意事项:不要同时使用重载构造函数和带默认值的构造函数。,#include

11、 using namespace std;class Box public:Box(int w=10,int h=10,int len=10);int volume();private:int height;int width;int length;,例3.4:将例3.3中的构造函数改用带默认值的参数,长、宽、高的默认值都是10。,如果在类外定义构造函数,应该在声明构造函数时指定默认参数值,在定义函数时可以不再指定默认参数值。,Box:Box(int w,int h,int len)height=h;width=w;length=len;int Box:volume()return(heigh

12、t*width*length);,int main()Box box1;coutbox1 体积=box1.volume()endl;Box box2(15);coutbox2 体积 box2.volume()endl;Box box3(15,30);coutbox3 体积 box3.volume()endl;Box box4(15,30,20);coutbox4 体积box4.volume()endl;return 0;,程序运行结果为:box1 体积=1000box2 体积=1500box3 体积=4500box4 体积=9000构造函数也可以改写成带参数初始化表的形式:Box:Box(in

13、t h,int w,int len):height(h),width(w),length(len)整个函数只需一行,简单方便。,3.2析构函数,作用:与构造函数相反,当对象的生命周期结束时,系统自动调用析构函数,收回对象占用的内存空间。析构函数的特征析构函数名以符号开始后跟类名析构函数没有数据类型、返回值、形参。由于没有形参所以析构函数不能重载。如果程序员没有定义析构函数,C+编译系统会自动生成一个析构函数。,例3.5 包含构造函数和析构函数的C+程序#include#include using namespace std;class Student public:Student(int n,

14、string nam,char s)num=n;name=nam;sex=s;coutConstructor called.endl;,Student()coutDestructor called.endl;void display()coutnum:numendl;coutname:nameendl;coutsex:sexendlendl;private:int num;string name;char sex;,int main()Student stud1(10010,Wang_li,f);stud1.display();Student stud2(10011,Zhang_fun,m);

15、stud2.display();return 0;,main函数前声明的类其作用域是全局的。程序运行结果如下:10010:Constructor called.num:10010 name:Wang_li sex:f10011:Constructor called.num:10011 name:Zhang_fun sex:m10011:Destructor called.10010:Destructor called.,3.3调用构造函数和析构函数的顺序,当定义多个对象时:先构造的后析构,后构造的先析构。,对象1 的构造函数,对象2 的构造函数,对象1 的析构函数,对象2 的析构函数,作用域概

16、念同样适用于类对象,3.4 对象数组,作为一种数据类型,可以定义类类型的数组,(就象int型的数组一样)。,例3.6 对象数组的使用方法。(长方体数组)#include using namespace std;class Box public:Box(int h=10,int w=12,int len=15):height(h),width(w),length(len)/带默认参数值和参数表 int volume();private:int height;int width;int length;,int Box:volume()return(height*width*length);int

17、main()Box a3=Box(10,12,15),Box(15,18,20),Box(16,20,26);cout“a0的体积是 a0.volume()endl;couta1的体积是 a1.volume()endl;couta2的体积是 a2.volume()endl;return 0;/每个数组元素是一个对象,运行结果如下:,a0的体积是 1800 a1的体积是 5400 a2的体积是 8320,3.5 对象指针,指针的含义是内存单元的地址,可以指向一般的变量,也可以指向对象。,3.5.1 指向对象的指针3.5.2 指向对象成员的指针3.5.3 this 指针,3.5.1指向对象的指针,

18、两种获取对象指针的方法:用取地址运算:&对象名运算的结果是该对象的起始地址,也称对象的指针。定义指针型对象变量,格式如下:类名*变量名表,class Timepublic:Time()hour=0;minute=0;sec=0;void set_time();void show_time();private:int hour;int minute;int sec;,void Time:set_time()cinhour;cinminute;cinsec;void Time:show_time()couthour:minute:“secendl;,在此基础上,有以下语句:,Time*pt;/定义

19、pt是指向Time类对象的指针Time t1;/定义Time类对象t1pt=/将对象t1的地址赋予pt程序在此之后就可以用指针变量访问对象的成员。(*pt).hourpt-hour(*pt).show_time()pt-show_time(),3.5.2 指向对象成员的指针,分类:指向数据成员的指针指向成员函数的指针,3.5.3 this 指针,什么是this指针?this指针是指向本类对象的指针。this指针存在于何处?每个成员函数中都包含this指针。举例:int Box:volume()/类的成员函数定义return(height*width*length);int Box:volume

20、(*this)/系统隐式调用this指针return(this-height*this-width*this-length);,3.6 共用数据的保护(关于类的),何为公用数据的保护?Const float PI=3.14159;/一般类型的公用数据保护确保共享的数据不被随意修改,从技术上把数据指定为只读型的。怎样保护?指定保护对象为const类型。,3.6.1 常对象3.6.2 常对象成员3.6.3 指向对象的常指针3.6.5 对象的常引用3.6.6 const 型数据小结*3.6.4 指向常对象的指针变量,作函数参数,不必另外开辟内存空间,提高时间和空间效率,3.6.1 常对象(const

21、对象),定义格式:const 类名 对象名(实参表);或 类名 const 对象名(实参表);作用:确定一个固定的对象,如新年开始时间;特点:常对象的数据成员不能修改;除构造函数和析构函数外,只能调用const型成员函数。如:const Time t1(10,15,36);/定义为常对象t1.get_time();/如get_time()为一般成员函数,错误const型成员函数:void get_time()const;,3.6.2 常对象成员,分类:(1)常数据成员(const数据成员)格式:const 类型 数据成员名 注意:常数据成员只能通过带参数初始表的构造函数进行初始化,不能更改(2

22、)常成员函数(const成员函数)定义格式:类型 函数名(形参表)const 注意:只能修改“可变的数据成员”“可变的数据成员”格式:mutable 类型 数据成员;,分析,例:const int hour;Time:Time(int h)hour=h;应该写成:Time:Time(int h):hour(h),/错误,表3.1,#includeusing namespace std;class Timeint hour;/非const的数据成员const int minute;/const数据成员public:void fun1(int h,int m)/非const的成员函数hour=h;

23、/修改h=hour;/引用/minute=m;/修改m=minute;/引用,void fun2(int h,int m)const/const的成员函数/hour=h;/修改h=hour;/引用/minute=m;/修改m=minute;/引用 Time(int h,int m):minute(m)/构造函数 hour=h;/minute=m;,int main()const Time t(10,20);/const对象/t.fun1(6,15);t.fun2(5,10);return 0;,3.6.3 指向对象的常指针,什么是指向对象的常指针?是一个指向对象的指针,指针的指向(地址)不允许

24、改变,指针的内容可以更改注意:须在定义时赋值格式:类名*const 指针变量名=对象地址举例:Time t1(10,12,15);Time*const p1=,3.6.5 对象的常引用,什么对象的常引用?某个已定义对象的别名,内容不能修改。格式:const 类名&形参对象名应用场合:以对象的常引用作函数参数,访问对象数据,但不修改对象数据。,#include using namespace std;class Time public:Time(int,int,int);int hour;int minute;int sec;Time:Time(int h,int m,int s)hour=h;

25、minute=m;sec=s;,例3.8,void fun1(Time,3.6.6 const 型数据的小结,3.7 对象的动态建立和释放,方法:C+提供了new和delete运算符,用来动态建立对象和释放对象。举例:例:Box*pt;/定义对象指针 pt=new Box;/动态建立对象 cout volume();/访问对象 delete pt;/动态释放对象,3.8 对象的赋值和复制,3.8.1对象的赋值 同类对象之间可以互相赋值。格式 对象1=对象2;对象1、对象2都是已建立好的同类对象。功能:将对象2值(所有数据成员的值)赋予对象1。注意:数据成员中不能含有动态分配的数据成员。,例3.

26、9 对象的赋值,#include using namespace std;class Box public:Box(int=10,int=10,int=10);int volume();private:int height;int width;int length;,Box:Box(int h,int w,int len)height=h;width=w;length=len;int Box:volume()return(height*width*length);,int main()Box box1(15,30,25),box2;coutbox1 体积=box1.volume()endl;b

27、ox2=box1;/对象的赋值 Box box3(box2);/对象的复制 coutbox2 体积=box2.volume()endl;coutbox3 体积=box3.volume()endl;return 0;运行结果如下:box1 体积=11250 box2 体积=11250 box3 体积=11250,3.8.2 对象的复制,什么是复制对象?按照一个对象克隆出另一个对象(从无到有)复制对象有两种格式:(1)类名 对象2(对象1);按对象1复制对象2。(2)类名 对象2=对象1,对象3=对象1,;按对象1复制对象2、对象3。复制构造函数,3.9静态成员,共享数据是C+的一种重要机制共享举

28、例 某班级面向对象程序设计课程的分数,每个学生对象有自己的分数,共享班级总分、平均分C+怎样提供数据共享机制?C+静态成员(3.9)、友元(3.10)实现对象之间、类之间的数据共享。,3.9.1 静态数据成员,静态数据成员定义格式:static 类型 数据成员名例:class Boxpublic:Box(int=10,int=10);int volume();static int height;/公有静态成员 private:int width;int length;,这三个数据成员有何不同?,静态数据成员的特性,设Box有 n个对象 box1boxn:n个对象共享一个height整型数据空间

29、如果某个对象修改了height 成员的值,其他 n-1个对象的 height 成员值也被改变。,静态数据成员的使用,(1)静态数据成员的初始化数据类型 类名:静态数据成员名=初值;由于一个类的所有对象共享静态数据成员,所以不能用构造函数为静态数据成员初始化,只能在类外专门对其初始化。(2)静态数据成员的引用用对象名引用静态成员(公有类型),或用类名引用静态成员(公有或私有类型)。,Box:Box(int w,int len)width=w;length=len;int Box:volume()return(height*width*length);int Box:height=10;/静态数据

30、成员初始化,例3.10 引用静态数据成员,int main()Box a(15,20),b(20,30);couta.heightendl;coutb.heightendl;coutBox:heightendl;couta.volume()endl;return 0;,程序执行结果:1010103000,3.9.2静态成员函数,作用:专门且只能用于访问静态成员函数定义格式:static 类型 静态成员函数名(形参表)调用格式:类名:静态成员函数(实参表)对象名.静态成员函数(实参表),例3.11 关于引用非静态成员和静态成员的具体方法,class Student private:int num

31、;int age;float score;static float sum;/私有静态成员只能被类引用 static int count;public:Student(int,int,int);void total();static float average();/静态成员函数;,Student:Student(int m,int a,int s)num=m;age=a;score=s;void Student:total()sum+=score;count+;float Student:average()/定义静态成员函数 return(sum/count);/都是静态数据成员float

32、Student:sum=0;/访问静态数据成员int Student:count=0;,int main()Student stud3=Student(1001,18,70),Student(1002,19,79),Student(1005,20,98);int n;coutn;for(int i=0;in;i+)studi.total();cout n 个学生的平均成绩是;cout Student:average()endl;return 0;,静态成员的使用自学举例,例:静态成员函数、静态数组及其初始化#include#includeclass A static int a20;int x

33、;public:A(int xx=0)x=xx;static void in();static void out();void show()coutx=xendl;int A:a20=0,0,;,完成对静态数组的输入输出,使用前需要初始化静态数组,void A:in()coutai;void A:out()for(int i=0;i20;+i)coutai=aiendl;void main()A:in();/调用静态成员函数in(),初始化静态数组a20 A:out();/调用静态成员函数out(),显示静态数组a20 A a;/定义A类的对象a a.out();/与A:out()同 a.sh

34、ow();/显示对象a的数据成员值,3.10友元,友元作用:访问类的私有成员,实现类和类之间共享数据。友元形式:一般函数;另一个类的成员函数;一个类(这个类中的所有成员函数都可以成为友元函数)。注意:友元破坏数据封装和数据隐藏,建议尽量不使用或少使用友元(交友慎重)。,3.10.2 友元类,何为友元类?将一个类声明为另一个类的友元(朋友)。友元类的功能:假定B类是A类的友元类,B类可访问A类中的所有成员。在A类中声明B类为友元类的格式:friend B;注意:(1)友元关系是单向的,不是双向的。(2)友元关系不能传递。,class B/3 public:void disp1(A temp)te

35、mp.x+;coutdisp1:x=temp.x endl;void disp2(A temp)temp.x-;coutdisp2:x=temp.x endl;,#include/1#include class Aprivate:int x;public:A()x=3;friend class B;,int main()/2A a;B b;b.disp1(a);b.disp2(a);return 0;,3.11类模板,模板种类:函数模板 书上P14;类模板:功能相同的类而数据类型不同,不必定义出所有类,只要定义一个可对任何类进行操作的类模板类模板举例:比较两个整数的类和比较两个浮点数的类。,定

36、义、使用类模板的格式:,定义类模板:template class 类模板名 类型参数名:按标识符取名。如有多个类型参数,每个类型参数都要以class为前导,两个类型参数之间用逗号分隔。类模板名:按标识符取名。类模板 内定义数据成员和成员函数的规则:用类型参数作为数据类型,用类模板名作为类。使用类模板,定义对象:类模板名 对象名;类模板名 对象名(实参表);,templateclass Compare private:int x,y;public:Compare(int a,int b)/构造函数 x=a;y=b;int max()return(xy)?x:y;int min()return(xy)?x:y;,定义类模板的格式:,numtype,numtype,numtype,numtype,numtype,用类模板定义对象的格式:,int main()Compare cmp1(3,7);cout cmp2(45.78,93.6);cout cmp3(a,A);coutcmp3.max()是两个字符中的大者.endl;coutcmp3.min()是两个字符中的小者.endl;return 0;,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 在线阅读 > 生活休闲


备案号:宁ICP备20000045号-1

经营许可证:宁B2-20210002

宁公网安备 64010402000986号