版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、 C+C+语言是语言是C C的扩充的扩充 扩充扩充 C C 语言语言 C+ C+ 语言语言 扩充的目的:扩充的目的: 支持面向对象程序设计支持面向对象程序设计 扩充的功能:扩充的功能: 类定义类定义 消息传递(类似函数调用)消息传递(类似函数调用) 继承、虚函数继承、虚函数第二章 类和对象第1页/共77页对象与封装 对象对象 相对独立的实体相对独立的实体 具有表示其状态、特征的属性具有表示其状态、特征的属性 具有表示其行为、功能的操作具有表示其行为、功能的操作 封装性:只有自身操作可访问对象属性封装性:只有自身操作可访问对象属性 面向对象方法面向对象方法 将分析、设计的系统和程序都抽象为对象组
2、成的模将分析、设计的系统和程序都抽象为对象组成的模型型 面向对象程序设计面向对象程序设计 运行中程序实例运行中程序实例 = = 若干对象实例若干对象实例 + + 交互控制交互控制 程序程序 = = 若干对象类(用于描述各种对象)若干对象类(用于描述各种对象) 对象类对象类 = = 程序模块程序模块 C+C+程序程序 = = 主函数主函数( (main) + main) + 若干类定义若干类定义第2页/共77页类 C+的类是把各种不同类型的数据(称为数据成员)和对数据的操作(成员函数)组织在一起而形成的用户自定义的数据类型。 C+中,类定义包括类说明和类实现两大部分。说明部分提供了对该类所有数据
3、成员和成员函数的描述,而实现部分提供了所有成员函数的实现代码。第3页/共77页类的定义 *.h class 类名 数据成员的说明public:方法成员的说明;第4页/共77页 说明: 类名由用户自己定,一般首字母大写 默认是private,只有类中的成员函数才能访问 注意:类定义的末尾有一分号 注意:不能在类定义中对数据成员进行初始化 class Location int x=25,y; /ERROR ;第5页/共77页class Date int year,month,day;public: Date(int y,int m,int d); void setYear(int y) ; voi
4、d setMonth(int m) ; void setDay(int d) ; int getYear( ); int getMonth( ); int getDay( ); ;类的定义第6页/共77页成员函数的定义1、将成员函数的定义直接写在类中 适合于成员函数规模较小的情况(内联函数)2、在类的定义体中只写出成员函数的原型说明,而成员函数的定义之后再写 通常将类的定义写在一个头文件(.h文件)中,成员函数的定义写在一个程序文件(.cpp文件)中 一般形式:返回类型 类名:成员函数名(参数说明)类体 第7页/共77页class Date int year,month,day;public:
5、Date(int y,int m,int d);void setYear(int y) ;void setMonth(int m) ;void setDay(int d) ;int getYear( ); int getMonth( ); int getDay( ) return day; /内联函数 ;第8页/共77页/date.cpp 实现部分#include date.h Date: Date(int y,int m,int d) year=y;month=m;day=d;int Date:getYear( ) return year;第9页/共77页int Date:getMonth(
6、 ) return month;int Date:getDay( ) return day;第10页/共77页void Date:setYear(int y ) year=y;void Date:setMonth(int m ) month=m;void Date:setDay(int d ) day=d;第11页/共77页#include #include date.hvoid main()Date k(2000,12,1);coutk.getMonth() year; c1.getYear(&c1);第17页/共77页例:有理数类的定义例:有理数类的定义#include class
7、 CRation long n;/ 分子分子long d;/ 分母分母public:CRation( long, long ); / 构造构造void Print( );/ 输出输出void Gcd( );/ 约分约分;第18页/共77页CRation:CRation( long n, long d )/ 对象创建时被调用this-n = n; / this是指向当前对象的指针this-d = d;void CRation:Print( void )cout n / d endl;第19页/共77页void CRation:Gcd( )int x = n, y = d, t;if( x y )
8、t = x; x = y; y = t; t=x%y; while( t != 0 ) x = y; y=t; t = x%y;n /= y; d /= y;第20页/共77页main( ) CRation r( 18, 27 );/ 分配空间,调构造函数分配空间,调构造函数 r.Print( ); / 输出输出 r.Gcd( ); / 约分约分 r.Print( ); 第21页/共77页例:动态整数数组类例:动态整数数组类作为对象的数组作为对象的数组唯一标识的实体唯一标识的实体封装数组元素、元封装数组元素、元素个数等信息素个数等信息责任功能责任功能按照下标的访问按照下标的访问数组大小可变数组
9、大小可变可获取元素个数可获取元素个数#include #include class Arrayint *pElems; int size; / 个数public:Array( int n ); / 构造Array( void ); / 析构void SetAt( int i, int v );int GetAt( int i ); / 存取int GetSize( void );第22页/共77页类设计要点独立性独立性表示独立的实体表示独立的实体以属性表示其特征以属性表示其特征以行为表示其担负的责任(功能、服务)以行为表示其担负的责任(功能、服务)封装性封装性不开放属性不开放属性提供足够的方法
10、,支持各种用途提供足够的方法,支持各种用途隐蔽内部数据结构隐蔽内部数据结构隐蔽方法的内部算法隐蔽方法的内部算法复用性复用性适用性强、功能丰富适用性强、功能丰富第23页/共77页方法的实现(1/2)Array:Array( int n )/ 构造n元素的数组pElems = new int n ;/ 动态生成size = n; Array:Array( void ) / 撤消前被自动调用delete pElems;/ 释放空间int Array:GetSize( void )return size; / 获得数组大小第24页/共77页方法的实现(2/2)void Array:SetAt( int
11、 i, int v )/ 按下标 i 赋值 vif( i = size )/ 超过范围 int *p = new int size +5 ;/ 开辟空间,复制数据 memcpy( p, pElems, size*sizeof(int) ); size+=5; delete pElems;/ 释放原数组空间 pElems = p;/ 保存首地址*(pElems + i ) = v;/ 赋值int Array:GetAt( int i )/ 按下标 i 取元素数据return i size? *(pElems + i): 0;第25页/共77页动态数组的使用动态数组的使用void main( )i
12、nt n;Array x(10); / 数组对象实例变量数组对象实例变量for( int i=0; i20; i+ )cout n;x.SetAt(i, n);for( i=0; ix.GetSize( ); i+ )cout x.GetAt(i) ;第26页/共77页程序分析 对象类对象类 = = 数据结构数据结构 + + 相关函数相关函数 属性属性 = = 结构分量结构分量 方法方法 = = 作用于结构的函数作用于结构的函数 对象实例变量对象实例变量 静态构造静态构造 局部变量、全局变量局部变量、全局变量 动态构造动态构造 new new 类名(参数表)类名(参数表) 函数定义函数定义 标
13、识所属的类标识所属的类 可以直接访问参数和本类的数据成员可以直接访问参数和本类的数据成员 函数调用函数调用 通过对象实例调用其方法通过对象实例调用其方法第27页/共77页消息传递 对象方法的激活 使用者向对象实例发消息 对象用方法函数响应消息 消息的组成 消息名 函数名 消息属性 参数值的列表 核心点 使用者仅关心消息的组成 对象决定哪个方法负责响应第28页/共77页消息传递消息响应不同类可以有同名方法函数同类中可以有原型不同的方法消息响应方法的选择1.消息名 = 方法名2.接收消息的对象(对象类)3. 匹配函数原型(参数个数、参数类型)第29页/共77页对象成员一个类的对象作为另一个类的数据
14、成员class X 类名1 成员名1 类名2 成员名2 . ;构造函数 X:X(参数表0):成员1(参数表1),成员2(参数表2) . 第30页/共77页建立X类对象时,先调对象成员的构造函数,然后才执行X类的构造函数对象成员构造函数的调用顺序取决于这些对象成员在类中的说明顺序析构函数的调用顺序与构造函数相反第31页/共77页#include Date.hclass Student_Info int No; char Name20; char Sex; Date Birthday; public: Student_Info(int n,char *a,char s,int y,int m,in
15、t d); Student_Info( ); int GetNo( ); char * GetName( ); char GetSex( ); ;第32页/共77页#include Student.hStudent_Info:Student_Info(int n,char *a,char s,int y,int m,int d):Birthday(y,m,d) No=n; strcpy(Name,a); Sex=s; Student_Info:Student_Info( ):Birthday(2000,1,1) No=0; strcpy(Name,); Sex=m; 第33页/共77页程序结构
16、一般分为三个文件:1)将类的说明作为头文件 .h2)将类的成员函数的实现放一个文件 .cpp3) 对类的使用放一个文件,包括main .cpp第34页/共77页 作业: 定义日期类 定义描述书的类,包括书名、价格、出版日期等第35页/共77页第三章 继承 现实世界中的一般特殊关系 人 学生 人 教师 类的继承 学生类继承人类 教师类继承人类 派生类:描述特殊的属性和行为 基类:描述一般的属性和行为第36页/共77页C+ 语言对继承的支持class 派生类 :public 基类/特殊属性/特殊方法;派生类继承了基类的属性和方法支持软件模块的复用 复用了基类的数据结构和成员函数第37页/共77页【
17、例】分别定义一个描述圆的类Circle和描述一个圆柱体的类Cylinder。第38页/共77页#ifndef Circle_H#define Circle_Hclass Circle /定义圆类 protected: double radius; public: Circle(double r) radius=r; void setradius(double r) radius=r; double getradius( ) return radius ; double area( ) return 3.14*radius*radius; ;#endif第39页/共77页#include Cir
18、cle.hclass Cylinder : public Circle /定义圆柱体类 double height; public: Cylinder(double r, double h); void setheight(double h); double getheight(); double area( ); /重新定义area()函数 ;第40页/共77页#include Cylinder.hCylinder:Cylinder(double r, double h): Circle(r) height=h; void Cylinder:setheight(double h) heigh
19、t=h; double Cylinder:getheight( ) return height; double Cylinder:area( ) /重新定义area()函数 return 2*Circle:area( )+2*3.14*radius*height; 第41页/共77页#include #include Cylinder.h#include Circle.hvoid main() Circle s1(10); Cylinder s2(2,5); cout圆柱体表面积:s2.area()endl; cout圆的面积是:s1.area()endl; 第42页/共77页在创建派生类的对
20、象时,由于派生类的对象包含了基类的数据成员,因此派生类的构造函数除初始化其自身定义的数据成员外,还必须对基类中的数据成员进行初始化,也就是说,派生类的构造函数要负责调用基类的构造函数。派生类的构造函数的定义格式如下:派生类名:派生类构造函数名(参数表):基类构造函数名(参数表) 第43页/共77页基类的对象只能调用基类的成员函数,不能调用派生类的成员函数在定义派生类的对象时,系统首先执行基类的构造函数,然后执行派生类的构造函数。而系统执行析构函数的顺序恰恰相反,即先执行派生类的析构函数,再执行基类的析构函数若在基类中没有定义任何构造函数,这时在派生类的构造函数的定义中可以省略对基类构造函数的调
21、用,此时系统将去调用基类的默认构造函数。 第44页/共77页多继承 定义多继承类的方式:class 派生类名:访问方式 基类1,访问方式 基类2 ; 其中:访问方式同单继承 多继承下派生类的构造函数必须同时负责所有基类构造函数的调用 在多继承下,派生类构造函数的定义格式:派生类构造函数名(参数表):基类名1(参数表1), 第45页/共77页 在多继承下,系统首先执行各基类的构造函数,然后再执行派生类的构造函数,处于同一层次的各基类构造函数的执行顺序与声明派生类时所指定的各基类顺序一致,而与派生类的构造函数定义中所调用基类构造函数的顺序无关。第46页/共77页第四章 多态性与虚函数 多态性 不同
22、事物以不同方式响应同一消息 演出 发消息 “暂停” 给 比赛 会议 产生不同的消息响应 消息响应 取决于接受消息的对象,而不是发送者第47页/共77页【例】#include class A int a;public: A(int i=0) a=i; void print(); ;void A:print () c o u t I n c l a s s A , p r i n t ( ) i s called.endl; 第48页/共77页class B:public A int b; public: B(int j=-1)b=j; void print(); ;void B:print ()
23、 coutIn class B, print() is called.print(); pb=&b; pb-print(); pa=&b; /基类指针可以指向派生类对象 pa-print(); 第50页/共77页第51页/共77页void commfun(A &aref) aref.print(); void main() A a; a.print(); commfun(a); /以基类A的对象a作实参 B b; b.print(); commfun(b); /以派生类B的对象b作实参 第52页/共77页第53页/共77页 分析:在派生类B中继承了基类A的 成 员 函
24、数print(),又定义了一个同名的print()函数。 这种改变在静态联编的基础上编译器并不知道。 必须通知编译器这种可能的改变,即需要进行动态联编。其方法就是在基类中将可能发生改变的成员函数声明为虚函数。第54页/共77页虚函数 声明虚函数的方法是在基类中的成员函数原型前加上关键字virtual。 其格式如下: class 类名 virtual 类型 函数名(参数表); ;第55页/共77页 当一个类的成员函数说明为虚函数后,在该类的派生类中定义与其基类虚函数原型相同的函数。 这时,当用基类指针指向这些派生类对象时,系统会在程序运行中根据所指对象的不同,自动选择派生类中的同名函数来代替基类
25、中的虚函数。第56页/共77页 虚函数在派生类中重新定义时,必须与基类中的函数原型完全相同,包括函数名、返回类型、参数个数和参数类型的顺序。这时无论在派生类的相应成员函数前是否加上关键字virtual,都将视其为虚函数。 如果函数原型不同,只是函数名相同,C+将视其为一般的函数重载,而不是虚函数。第57页/共77页#include class Ppublic:virtual void print() coutParentClassendl;class A: public Ppublic:virtual void print() coutSubClass1endl;class B: public
26、 Ppublic:virtual void print() coutSubClass2print(); s1=&obj2; s1-print(); 通过指针第59页/共77页class Apublic:virtual void Print()coutParentendl;class B:public Apublic:virtual void Print() coutSubclassendl;void show(A &a)a.Print();通过引用第60页/共77页void main() B b; show(b); 第61页/共77页纯虚函数 在基类中只声明虚函数而不给出具体的
27、函数定义体,将它的具体定义放在各派生类中,称此虚函数为纯虚函数。 通过该基类的指针或引用就可以调用所有派生类的虚函数,基类只是用于继承,仅作为一个接口,具体功能在派生类中实现。 形式:virtual 类型 函数名(参数表) =0;第62页/共77页抽象类 若一个类至少有一个纯虚函数,就称该类为抽象类。 抽象类中可以有多个纯虚函数,也可以定义其他非纯虚函数。 第63页/共77页 不能声明抽象类的对象,但可以声明指向抽象类的指针变量和引用变量。 如果派生类中没有重新定义基类中的纯虚函数,则在派生类中必须再将该虚函数声明为纯虚函数。 从抽象类可以派生出具体或抽象类。 引入抽象类的目的,主要是为了能将相关类组织在一个类继承结构中,并通过抽象类来为这些相关类提供统一的操作接口。第64页/共77页 【例】 设计一个抽象类shape,它表示具有形状的东西,体现了抽象的概念,在它下面可以派生出多种具体形状,比如三角形、矩形。#includeclass Shape protected: double x,y; public: void set(double i
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 报关内勤工作介绍课件
- 2026年版全国计算机等级考试模拟试卷带答案
- 2026年车削加工工艺模拟试题(含答案)
- 2026年殡仪行业考试模拟试卷带答案
- 2026年广东广州市暨南大学博士后招聘模拟试卷(含答案)
- 国家开放大学电大本科市场营销策划(本)2025期末模拟试题及参考答案
- 2026年北森招聘考试模拟试卷带答案
- 2026年班组安全生产培训模拟试卷目带答案
- 2026年安徽药学单招模拟试题(含答案)
- 2026年施工吊装考试题库及参考答案
- 天津港集团招聘笔试真题
- 【初中 地理】知识点汇Z-2025-2026学年七年级地理上学期(湘教版2024)
- 广东省广州市2026届高三年级上学期12月调研测试(广州零模)历史试卷
- 2025届高三下学期《十八而志大任始承-高三成人礼》主题班会课件
- 船舶船员心理卫生指南
- 仪表管理标准制度
- 宫颈癌疫苗接种知识培训课件
- 检验室现场管理制度
- 学校交通安全家长会课件
- 临床技术操作规范麻醉学分册
- 泰勒《课程与教学的基本原理》讲义
评论
0/150
提交评论