版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第第5 5讲讲 类与对象类与对象(3)(3)多个类之间的关系多个类之间的关系问题问题构造函数构造函数只能有一个。(判断正误)只能有一个。(判断正误)析构函数析构函数只能有一个。只能有一个。 (判断正误)(判断正误)构造函数构造函数与与析构函数析构函数的调用时机?的调用时机?拷贝(复制)构造函数与构造函数的拷贝(复制)构造函数与构造函数的区别区别?它的?它的调用时机调用时机?3组合的概念组合的概念类中的成员数据是另一个类的对象。类中的成员数据是另一个类的对象。可以在已有抽象的基础上实现更复杂的可以在已有抽象的基础上实现更复杂的抽象。抽象。类 的 组 合4举例举例class Point class
2、 Point private:private: float x, y; / float x, y; /点的坐标点的坐标public:public: Point(float h, float v); Point(float h, float v); float getX(); / float getX(); /取取X X坐标坐标 float getY(); / float getY(); /取取Y Y坐标坐标 void draw(); /void draw(); /在在(x,y)(x,y)处画点处画点;/./.函数的实现略函数的实现略类 的 组 合class Line class Line pr
3、ivate:private: Point p1, p2; / Point p1, p2; /线段的两个端点线段的两个端点public:public: Line(Point a, Point b); / Line(Point a, Point b); /构造函数构造函数 void draw(void); /void draw(void); /画出线段画出线段;/./.函数的实现略函数的实现略56类组合的构造函数设计类组合的构造函数设计原则:原则:不仅要负责对本类中的基本类型成员不仅要负责对本类中的基本类型成员数据赋初值,也要对对象成员初始化。数据赋初值,也要对对象成员初始化。( (思思考为什么考
4、为什么? ?) )声明形式:声明形式:类名类名:类名类名( (对象成员所需的形参,本类成员形参对象成员所需的形参,本类成员形参) ) : :对象对象1(1(参数参数) ),对象,对象2(2(参数参数) ),. 本类初始化本类初始化 见见P119P119类 的 组 合7类组合的构造函数调用类组合的构造函数调用构造函数调用顺序:先调用内嵌对象的构造函数调用顺序:先调用内嵌对象的构造函数(按内嵌时的声明顺序,先声构造函数(按内嵌时的声明顺序,先声明者先构造)。然后调用本类的构造函明者先构造)。然后调用本类的构造函数。(析构函数的调用顺序相反)数。(析构函数的调用顺序相反)类 的 组 合类组合的构造函
5、数调用类组合的构造函数调用初始化列表中未出现的内嵌对象,用默认初始化列表中未出现的内嵌对象,用默认构造函数(即无形参的)初始化构造函数(即无形参的)初始化系统自动生成的隐含的默认构造函数中,系统自动生成的隐含的默认构造函数中,内嵌对象全部用默认构造函数初始化内嵌对象全部用默认构造函数初始化其它见其它见P118P1189类的组合举例(二)类的组合举例(二)class Part /部件类部件类public: Part(); Part(int i); Part(); void Print();private: int val;类 的 组 合class Whole public: Whole(); W
6、hole(int i, int j, int k); Whole(); void Print();private: Partone; Parttwo; int date;10Whole:Whole() date=0;Whole:Whole(int i, int j, int k) : two(i), one(j), date(k)/.其他函数的实现略11分析例4-4 p11813前向引用声明类应该先声明,后使用如果需要在某个类的声明之前,引用该类,则应进行前向引用声明。前向引用声明只为程序引入一个标识符,但具体声明在其他地方。类 的 组 合14前向引用声明举例class B; /前向引用声明c
7、lass A public: void f(B b);class B public: void g(A a);类 的 组 合15前向引用声明注意事项使用前向引用声明虽然可以解决一些问题,但它并不是万能的。需要注意的是,尽管使用了前向引用声明,但是在提供一个完整的类声明之前,不能声明该类的对象,也不能在内联成员函数中使用该类的对象。请看下面的程序段:class Fred; /前向引用声明class Barney Fred x; /错误:类Fred的声明尚不完善;class Fred Barney y;类 的 组 合16前向引用声明注意事项应该记住:当你使用前向引用声明时,你应该记住:当你使用前向
8、引用声明时,你只能使用被声明的符号,而不能涉及类的只能使用被声明的符号,而不能涉及类的任何细节。任何细节。类 的 组 合17前向引用声明注意事项class Fred;/前向引用声明 class Barney public: void method() x.yabbaDabbaDo();/错误:Fred类的对象在定义之前被使用 private: Fred &x;/正确,经过前向引用声明,可以声明Fred类的对象引用; class Fred public: void yabbaDabbaDo();private: Barney &y; 类 的 组 合结构体结构体是一种特殊形态的类结
9、构体是一种特殊形态的类与类的唯一区别:类的缺省访问权限是与类的唯一区别:类的缺省访问权限是privateprivate,结构体的缺省访问权限是结构体的缺省访问权限是publicpublic结构体存在的主要原因:与结构体存在的主要原因:与C C语言保持兼容语言保持兼容什么时候用结构体而不用类什么时候用结构体而不用类定义主要用来保存数据、而没有什么操作的类定义主要用来保存数据、而没有什么操作的类型型人们习惯将结构体的数据成员设为公有,因此人们习惯将结构体的数据成员设为公有,因此这时用结构体更方便这时用结构体更方便18结构体与联合体结构体的定义和初始化结构体定义结构体定义structstruct 结
10、构体名称结构体名称 公有成员公有成员protected:protected: 保护型成员保护型成员private:private: 私有成员私有成员;一些结构体变量的初始化可以用以下形式一些结构体变量的初始化可以用以下形式类型名类型名 变量名变量名 = = 成员数据成员数据1 1初值初值, , 成员数据成员数据2 2初值初值, , ;19结构体与联合体20无名联合无名联合无名联合没有标记名,只是声明一个成员无名联合没有标记名,只是声明一个成员项的集合,这些成员项具有相同的内存地项的集合,这些成员项具有相同的内存地址,可以由成员项的名字直接访问。址,可以由成员项的名字直接访问。例:例:union
11、 union int i; int i; float f; float f; 在程序中可以这样使用:在程序中可以这样使用:i = 10;i = 10;f = 2.2;f = 2.2;结构体与联合体位域位域位域的声明形式位域的声明形式 数据类型说明符数据类型说明符 成员名成员名 : : 位数位数; ;位域的作用位域的作用通过通过“打包打包”,使类的不同成员共享相同的字,使类的不同成员共享相同的字节,从而节省存储空间。节,从而节省存储空间。注意事项注意事项具体的打包方式,因编译器而异;具体的打包方式,因编译器而异;只有只有boolbool、charchar、intint和枚举类型的成员,允许和枚举
12、类型的成员,允许定义为位域;定义为位域;节省空间,但可能增加时间开销。节省空间,但可能增加时间开销。21深 度 探 索例4-9设计一个结构体存储学生的成绩信息,需设计一个结构体存储学生的成绩信息,需要包括学号、年级和成绩三项内容,学号要包括学号、年级和成绩三项内容,学号的范围是的范围是0 0到到99,999,99999,999,999,年级分为,年级分为freshmanfreshman、sophomoresophomore、juniorjunior、seniorsenior四四种,成绩包括种,成绩包括A A、B B、C C、D D四个等级。四个等级。22深 度 探 索例4-9#include
13、using namespace std;enum Level FRESHMAN, SOPHOMORE, JUNIOR, SENIOR ;enum Grade A, B, C, D ;class Student public:Student(unsigned number, Level level, Grade grade): number(number), level(level), grade(grade) void show();private:unsigned number : 27;Level level : 2;Grade grade : 2;23深 度 探 索例4-9void St
14、udent:show() cout Number: number endl;cout Level: ;switch (level) case FRESHMAN: cout freshman; break;case SOPHOMORE: cout sophomore; break;case JUNIOR: cout junior; break;case SENIOR: cout senior; break;cout endl;cout Grade: ;switch (grade) case A: cout A; break;case B: cout B; break;case C: cout C
15、; break;case D: cout D; break;cout endl;24深 度 探 索例4-9int main() Student s(12345678, SOPHOMORE, B);cout Size of Student: sizeof(Student) endl;s.show();return 0;运行结果:(运行结果第一行会因编译环境的不同而有所差异)运行结果:(运行结果第一行会因编译环境的不同而有所差异)Size of Student: 4Number: 12345678Level: sophomoreGrade: B25深 度 探 索临时对象与类型转换( 例例4-24-
16、2中中PointPoint构造函数:构造函数:Point(Point(intint xx = 0, xx = 0, intint yyyy = = 0) 0) )临时对象的显式创建临时对象的显式创建可以直接调用类的构造函数显式创建临时对象可以直接调用类的构造函数显式创建临时对象例:例:Line x(Point(1, 1), Point(4, 5);Line x(Point(1, 1), Point(4, 5);临时对象到表达式执行完毕后即销毁临时对象到表达式执行完毕后即销毁单参数构造函数可以设立类型转换单参数构造函数可以设立类型转换Point(1)Point(1)表示创建一个临时对象,同时也表
17、示显式类型表示创建一个临时对象,同时也表示显式类型转换转换与与Point(1)Point(1)等价的形式:等价的形式: (Point) 1(Point) 1 static_caststatic_cast(1)(1)无论形式为何,执行转换时都会创建临时对象无论形式为何,执行转换时都会创建临时对象26深 度 探 索static_caststatic_cast转换类似于转换类似于C/C+C/C+里面的强制类型转换。里面的强制类型转换。 dynamic_castdynamic_cast转换是根据基类派生类的原则进行转换,把一个派转换是根据基类派生类的原则进行转换,把一个派生类转换为基类使用这个转换。生
18、类转换为基类使用这个转换。 const_castconst_cast转换是去掉转换是去掉constconst变量的变量的constconst隐含转换隐含转换由构造函数确立的类型转换,可以隐含执行例:Line x(1, 4);效果:构造以(1,0)和(4,0)两坐标为端点的线段,这里Point的构造函数被隐含调用避免隐含转换的发生在构造函数中使用explicit关键字,explicit要写在类定义中的构造函数前27深 度 探 索例4-10#include using namespace std;class Complex /复数类private: float real, imag;/复数的实部和
19、虚部public: /构造函数,可以当作隐式类型转换使用 Complex(float real = 0, float imag = 0) : real(real), imag(imag) Complex add(Complex c) /复数加法,生成临时对象并返回 return Complex(real + c.real, imag + c.imag); Complex sub(Complex c) /复数减法,生成临时对象并返回 return Complex(real - c.real, imag - c.imag); Complex mul(Complex c) /复数乘法,生成临时对象并
20、返回 return Complex(real * c.real - imag * c.imag, real * c.imag + imag * c.real); 28深 度 探 索例4-10 void show() /显示复数显示复数 if (imag = 0) cout real + imag i endl; else cout real - -imag i endl; ;int main() Complex z(1, 2);/z = 1 + 2iz.add(Complex(3, 4).show(); /Complex(3, 4)是临时对象是临时对象static_cast(5).sub(z)
21、.show(); /输出输出5 z,使用了显示,使用了显示类型转换类型转换z.mul(-3.0f).show(); /输出输出z * (-3),使用了隐含类型转换,使用了隐含类型转换return 0;运行结果:运行结果:4 + 6i4 - 2i-3 - 6i29深 度 探 索成员函数的调用成员函数的调用成员函数调用的实现机制成员函数调用的实现机制问题的关键:如何传递调用的目的对象问题的关键:如何传递调用的目的对象解决办法:把目的对象的引用当作参数传递解决办法:把目的对象的引用当作参数传递30void Clock:setTime(int newH, int newM, int newS) hou
22、r = newH; minute = newM; second = newS;void Clock_setTime(_Clock &_this, int newH, int newM, int newS) _this.hour = newH; _this.minute = newM; _this.second = newS;Clock_setTime(myClock, 8, 30, 30);myClock.setTime(8, 30, 30);深 度 探 索构造函数的调用构造函数的调用31Line:Line(Point xp1, Point xp2) : p1(xp1), p2(xp2
23、) double x = p1.getX() - p2.getX(); double y = p1.getY() - p2.getY(); len = sqrt(x * x + y * y);void Line_Line(_Line &_this, _Point xp1, _Point xp2) Point_Point(_this.p1, xp1); Point_Point(_this.p2, xp2); double x = Point_getX(_this.p1) - Point_getX(_this.p2); double y = Point_getY(_this.p1) - Point_getY(_this.p2); _this.len = sqrt(x * x + y * y);Line line(myp1, myp2);_Line line;Line_Line(line, myp1, myp2);先分配空间,再调用构造函数先分配空间,再调用构造函数深 度 探 索对象作为参数的传递方式对象作为参数的传递方式对象参数的传递方式对象参数的传递方式通过运行栈来传递通过运行栈来传递主调函数调用拷贝构造函数,在运行栈的传参主调函数调用拷贝构造函数,在运行栈的传参区域上创建对象区域上创建对象被调函数可以读取传参区域上
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 二零二五年度法律服务机构兼职律师服务合同3篇
- 2025年度公司签约带货主播虚拟偶像合作合同3篇
- 二零二五年度养殖场养殖场养殖技术交流与合作合同3篇
- 2025年度建筑工程施工现场管理三方协议3篇
- 二零二五年度全新码头租赁合同及港口货物装卸服务协议3篇
- 2025年度XX教育机构二零二五年度教育贷款协议3篇
- 2025年度大学毕业生就业就业能力评估与培训合同3篇
- 2025年度高新技术产业竞业禁止劳动合同范本解析3篇
- 2025年度高效农业机械买卖合同协议书模板3篇
- 2025年度宠物店专业连锁品牌形象设计与授权合同3篇
- 【供应链视角下的光明乳业存货管理问题研究9700字】
- DL-T1069-2016架空输电线路导地线补修导则
- 个体诊所医疗器械自查报告
- 交响音乐赏析智慧树知到期末考试答案章节答案2024年西安交通大学
- JTG-D82-2009公路交通标志和标线设置规范
- CT增强检查的护理
- (完整版)公务员考试行测答题卡-高清A4标准打印版
- 初中化学实验安全教育
- 《预测与决策教程第2版》(习题解答)机工版
- GT 42456-2023 工业自动化和控制系统信息安全 IACS组件的安全技术要求
- 服装色彩搭配智慧树知到期末考试答案2024年
评论
0/150
提交评论