c++第9章关于类和对象的进一步讨论

上传人:E**** 文档编号:90581806 上传时间:2019-06-13 格式:PPT 页数:84 大小:192.50KB
返回 下载 相关 举报
c++第9章关于类和对象的进一步讨论_第1页
第1页 / 共84页
c++第9章关于类和对象的进一步讨论_第2页
第2页 / 共84页
c++第9章关于类和对象的进一步讨论_第3页
第3页 / 共84页
c++第9章关于类和对象的进一步讨论_第4页
第4页 / 共84页
c++第9章关于类和对象的进一步讨论_第5页
第5页 / 共84页
点击查看更多>>
资源描述

《c++第9章关于类和对象的进一步讨论》由会员分享,可在线阅读,更多相关《c++第9章关于类和对象的进一步讨论(84页珍藏版)》请在金锄头文库上搜索。

1、第9章 关于类和对象的进一步讨论,9.1 构造函数 9.2 析构函数 9.3 调用构造函数和析构函数的顺序 9.4 对象数组 9.5 对象指针 9.6 对象的动态建立和释放 9.7 对象的赋值和复制 9.8 静态成员 9.9 友元,9.1 构造函数 9.1.1 对象的初始化,在建立一个对象时,常常需要作某些初始化的工作,例如对数据成员赋初值。如果一个数据成员未被赋值,则它的值是不可预知的,因为在系统为它分配内存时,保留了这些存储单元的原状,这就成为了这些数据成员的初始值。这种状况显然是与人们的要求不相符的,对象是一个实体,它反映了客观事物的属性(例如时钟的时、分、秒的值),是应该有确定的值的。

2、,类的数据成员是不能在声明类时初始化的。,class student int sno=10; string name=“wang“; ; 编译错误: ISO C+ forbids initialization of member sno ISO C+ forbids initialization of member name 为什么?,如果一个类中所有的成员都是公用的,则可以在定义对象时对数据成员进行初始化。如 class Time public: /声明为公用成员 int hour; int minute; int sec; ; Time t1=14,56,30; /将t1初始化为14:56

3、:30,但是,如果数据成员是私有的,或者类中有private或protected的成员,就不能用这种方法初始化。 类的封装性就体现在一部分数据是不能让外界访问的。所以直接在非成员函数中访问类对象的私有或者保护数据是不允许的。 类对象的初始化的任务,自然就落到了类的成员函数身上,因为它们可以访问私有及保护数据成员。,我们将初始化构想成下面的形式: class student int sno; double gpa; public: void init( ) sno=10; gpa=85; . /其他公有成员 ;,void fun student s; s.init(); /类的初始化 . 将初始

4、化的工作交由init()成员函数无可非议,但让系统多了一道处理初始化的解释与执行。,9.1.2 构造函数的作用,为了解决这个问题,C+提供了构造函数(constructor)来处理对象的初始化。构造函数是一种特殊的成员函数,与其他成员函数不同,不需要用户来调用它,而是在建立对象时自动执行。构造函数的名字必须与类名同名,而不能由用户任意命名,以便编译系统能识别它并把它作为构造函数处理。它不具有任何类型,不返回任何值。构造函数的功能是由用户定义的,用户根据初始化的要求设计函数体和函数参数。,#include using namespace std; class student int sno; d

5、ouble gpa; public: student( ); void setStudent(int s,double g); int getSno( ); double getGpa( ); ;,student:student( ) sno=0; gpa=0; void student:setStudent(int s,double g) sno=s; gpa=g; ,int student:getSno( ) return sno; double student:getGpa( ) return gpa; ,int main( ) student a,b; a.setStudent(10,

6、85); couta.getSno( )“ “a.getGpa()endl; coutb.getSno( )“ “b.getGpa()endl; return 0; 构造函数没有返回类型,函数体中也不允许返回值,因为构造函数专门用于创建对象和为其初始化,它不能随意被调用。没有返回类型,正显得它与众不同。,注意:,在创建类对象时,构造函数被自动调用。 构造函数没有返回类型,函数体中也不允许返回值。 构造函数不需用户调用,也不能被用户调用。 构造函数专门用于创建对象和为其初始化,一般不提倡在构造函数中加入与初始化无关的内容。 如果用户自己没有定义构造函数,则C+系统会自动生成一个构造函数,只是这个

7、构造函数的函数体是空的,也没有参数,不执行初始化操作。,9.1.3 带参数的构造函数,前面介绍的构造函数不能完全满足初始化的要求,它只能将对象构造成千篇一律的对象值,我们不得不再调用一个初始化成员函数将数据存到该对象中去。 构造函数在参数规定上和普通函数一样,可以有任意多个参数。,#include using namespace std; class student int sno; double gpa; public: student(int s,double g); int getSno( ); double getGpa( ); ;,student:student(int s,doub

8、le g) sno=s; gpa=g; int student:getSno() return sno; double student:getGpa() return gpa; ,int main() student a(10,85),b(11,90); couta.getSno()“ “a.getGpa()endl; coutb.getSno()“ “b.getGpa()endl; return 0; ,输出: 85 11 90,9.1.4 用参数初始化表对数据成员初始化,C+还提供另一种初始化数据成员的方法参数初始化表来实现对数据成员的初始化。这种方法不在函数体内对数据成员初始化,而是在函

9、数首部实现。,class student int sno; double gpa; public: student(int s,double g):sno(s),gpa(g) ; int getSno( ); double getGpa( ); ;,9.1.5 构造函数的重载,构造函数可以被重载。 重载的规则与普通函数重载相同。,#include using namespace std; class student int sno; double gpa; public: student( ); student(int s); student(int s,double g); int getS

10、no( ); double getGpa( ); ;,student:student() sno=0; gpa=0; student:student(int s) sno=s; gpa=0; student:student(int s,double g) sno=s; gpa=g; ,int student:getSno() return sno; double student:getGpa() return gpa; ,int main() student a,b(11),c(12,98); couta.getSno()“ “a.getGpa()endl; coutb.getSno()“ “

11、b.getGpa()endl; coutc.getSno()“ “c.getGpa()endl; return 0; ,输出: 0 0 0 12 98,注意:,无参的构造函数属于默认构造函数。一个类只能有一个默认构造函数。 如果在建立对象时选用的是无参构造函数,应注意正确书写定义对象的语句。 尽管在一个类中可以包含多个构造函数,但是对于每一个对象来说,建立对象时只执行其中一个构造函数,并非每个构造函数都被执行。,9.1.6 使用默认参数的构造函数,构造函数中参数的值既可以通过实参传递,也可以指定为某些默认值,即如果用户不指定实参值,编译系统就使形参取默认值。 student(int sno,d

12、ouble g=0);,9.1.7 关于默认构造函数,C+规定,每个类必须有一个构造函数。没有构造函数,就不能创建任何对象。 若未提供一个类的构造函数(一个都没有定义),则C+提供一个默认的构造函数,该默认构造函数是个无参构造函数,它仅负责创建对象,而不做任何初始化工作。 只要一个类定义了一个构造函数(不一定是无参构造函数),C+就不再提供默认的默认构造函数。 与变量定义类似,在用默认构造函数创建对象时,如果创建的是全局对象或静态对象,则对象的值全为0,否则是不确定的。,9.2 析构函数,一个类可能在构造函数里分配资源,这些资源需要在对象不复存在以前被释放。 例如,如果构造函数打开了一个文件,

13、文件就要被关闭;如果构造函数从堆中分配了内存,这块内存在对象消失之前必须被释放。 析构函数允许类自动完成这些清理工作。,析构函数也是特殊的类成员函数,它没有返回类型,没有参数,不能随意调用,也没有重载。 析构函数只是在类对象生命期结束的时候,由系统自动调用。 析构函数名与类名相同,前面加上。 student( );,#include using namespace std; class student char* name; public: student( ); student( ); string getName( ); ;,student:student() name=new char2

14、0; /分配堆空间 cout“构造函数“endl; student:student() delete name; /释放堆空间 cout“析构函数“endl; string student:getName() return name; ,int main() student a; couta.getName()endl; return 0; ,输出: 构造函数 noname 析构函数,9.3 调用构造函数和析构函数的顺序,析构函数以调用构造函数相反的顺序被调用。,#include using namespace std; class student string name; public: s

15、tudent(string n); student( ); ;,student:student(string n) name=n; cout“构造对象:“nameendl; student:student() cout“析构对象:“nameendl; ,int main( ) student s1(“a“),s2(“b“); cout“返回到main( )函数“endl; return 0; ,输出结果 构造对象:a 构造对象:b 返回到main( )函数 析构对象:b 析构对象:a,析构函数小结:,析构函数名与类名相同,但前面加上字符。 析构函数无函数返回类型,在这方面与构造函数是一样的,但

16、析构函数不带任何参数。 一个类有一个且只有一个析构函数,这也与构造函数不同。析构函数也可以默认。 注销对象时,系统自动调用析构函数。,9.4 对象数组,数组不仅可以由简单变量组成(例如整型数组的每一个元素都是整型变量),也可以由对象组成(对象数组的每一个元素都是同类的对象)。,#include using namespace std; class Box private: int height; int width; int length; public: Box(int h=10,int w=12,int len=15): height(h),width(w),length(len) int volum

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 高等教育 > 大学课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号