面向对象程序设计C++课件.ppt_第1页
面向对象程序设计C++课件.ppt_第2页
面向对象程序设计C++课件.ppt_第3页
面向对象程序设计C++课件.ppt_第4页
面向对象程序设计C++课件.ppt_第5页
已阅读5页,还剩145页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第一章 面向对象及c+基础知识,一、面向过程与面向对象,c+的历史 simula67、ada、cpl、 bcpl、b语言、c语言、带类的c、c+,机器语言,汇编语言,高级语言,自然语言,面向对象,面向过程,抽象:一组对象的共同特征抽象为类。 封装:将一组数据及其相关的操作集合在一起。like a 饮料机。 继承:一个对象可以获得其他对象的特征。 多态性:不同对象调用相同的接口,但结果不同。,二、面向对象程序设计方法,三、c+新的风格(1/5),输入/输出 scanf(“%d”,&i)cini printf(“%d”,i)couti 不需要记格式说明符,c+根据数据类型自动匹配。,三、c+新的风格(2/5),灵活的注释 couti; /输出i的值 新的换行符 coutiendl; /输出i的值,三、c+新的风格(3/5),告别宏定义 无参数宏 #define n 10const int n=10; 有参数宏 #define max(x,y) xy?x:y inline int max(int x,int y) return xy?x:y; 可以在编译时做数据类型的校验,避免隐含的错误。,三、c+新的风格(4/5),使用函数原型和缺省参数 函数原型 返回值类型 函数名(参数列表); 缺省参数 int func(int x,int y=1,int z=2);,参数列表中的参数名称可以没有,缺省参数必须全部在参数列表最后,三、c+新的风格(5/5),新的内存分配函数 mallocnew freedelete new不需要做类型转换。 int *p=new int(5); *p=8; delete p; int *q=new int5; q2=5; delete q;,四、内联函数,内联函数的运行方式和有参数宏相同。 内联函数有两种形式: 有inline的函数 在类定义中给出函数体的函数,五、引用(1/5),引用相当于给变量起个别名。 用 /输出20,五、引用(2/5),对const变量/对不同数据类型变量的引用不共用内存。 const int num = 10; int /输出20,五、引用(3/5),不能声明: 引用的引用 int,五、引用(4/5),引用作为函数参数时,形参的变化将会影响实参。,int swap(int 结果为:20,10,五、引用(5/5),引用作为函数返回值,函数调用可以放在等号左边。,int a=1,2,3,4,5; int 结果为:1,2,10,4,5,第二章 类和对象,第二章 类和对象 一、定义类(1/2),class 类名 访问权限: 数据成员; 函数成员; ,public private(缺省值) protected,class location private: int x,y; public: int getx() return x; int gety(); void init(int a,int b) x=a;y=b; ; int location:gety() return y;,一、定义类(2/2),不能对变量初始化,类定义完成必须加;,:为作用域运算符/类成员名限定符,二、使用类和对象,location p1,*p2; p1.init(1,2); p2 = /错,类的实例化,分配内存,成员选择运算符,三、内联成员函数,location类中的init、getx函数均为内联函数,gety不是。如果gety换成下面的形式,也将成为内联函数。 inline int location:gety() return y;,四、成员函数重载及缺省参数,成员函数重载:函数名相同,但参数(类型/个数)不同。 int getx(int a); int getx(); 缺省参数:将init改为 void init(int a=0,int b=0) x=a; y=b; p1.init(); p1.init(3); p2-init(3,3);,五、this指针,类的数据成员可以在类的函数成员中被访问。why? 不同对象的数据成员不互相影响。why? 不同对象调用函数成员时,this指针指向不同的对象。 return x;return this-x;,六、结构和联合,关键词class可以被换成struct、union来定义类。 struct:成员的访问权限缺省为public。 union:成员的访问权限缺省为public,且某时刻只有一个成员出现。 联合不能做基类和派生类 联合中不能说明虚函数 无名联合不能有成员函数,七、类作用域(1/3),说明类时的一对 形成类作用域。 成员函数内的标识符: 局部变量=类作用域=全局变量 class a int i=10; int i; int a:geti() public: int i=20;return i; int geti(); a a; ; couta.geti();,七、类作用域(2/3),类中定义的枚举成员,可以用类成员名限定存取,也可以用成员选择运算符存取。 类说明分定义性说明和引用性说明两类,在引用性说明阶段不能实例化对象,只能说明对象指针或引用。,七、类作用域(3/3),class a public: enum colorred,green,blue; a a; /错 a *p; a ,八、空类/嵌套类,空类:没有任何成员的类。 嵌套类:在另一个类中声明的类。一般嵌套类只用于它所声明的类中。 class a public: class b int i; ; b b; ;,九、类对象的性质及存取,对象之间可以互相赋值。 对象可以用作数组元素。 可以说明指向对象的指针 对象可用作函数参数,为值调用 一个对象可以做另一个对象的成员(对象成员),第三章 构造函数与析构函数,第三章 构造函数与析构函数 一、构造函数(1/3),类中与类同名且没有返回值类型的成员函数构造函数。 class a int k; public: a(); a(int); ;,可以有多个,一、构造函数(2/3),声明对象 new对象,构造函数在实例化对象时将被调用。 a:a() cout“a()”endl; a:a(int i) k=i;cout“a(”i“)”endl; a a; /输出a() a *c; a /输出a(5),一、构造函数(3/3),缺省构造函数:无参数的构造函数。缺省什么都不做。 复制初始化构造函数:参数类型为 类名,二、析构函数(1/2),类中名称为类名、没有返回值类型、没有参数的成员函数析构函数。 class a int k; public: a(); a(int); a(); ;,只有一个,二、析构函数(2/2),对象生命期结束 delete对象,析构函数在对象生命期结束时将被调用。 a:a() cout“a()”endl; main() a a; a *c; c = new a(5); delete c; /输出a() /对象a生命期结束,输出a(),三、构造函数类型转换,类的构造函数可以完成从基本数据类型到类类型的转换。 转换过程为:先建立隐藏对象,使用完成后将隐藏对象析构。 参见p49.cpp,四、对象初始化(1/2),注意指针数据成员。 参见p50.cpp,四、对象初始化(2/2),如果函数参数为对象,初始化形参时需要调用复制初始化构造函数。 如果函数返回值为对象,也需要调用复制初始化构造函数。 参见p51.cpp,五、对象赋值,缺省的赋值操作完成逐成员赋值。 自定义赋值操作格式为: 类名& operator=(类名&) 对象之间互相赋值时该函数将被调用。 obj1 = obj2obj1.operator=(obj2) 参见p54.cpp,六、对象成员(1/2),类中具有类类型的数据成员称为对象成员。 对象成员一般通过成员初始化列表初始化。 对象成员的构造函数先调用。 多个对象成员构造函数的调用顺序取决于在类中说明的顺序,与成员初始化列表中的顺序无关。 析构函数的调用顺序完全相反。 参见p56.cpp,六、对象成员(2/2),class x 类1 obj1; 类2 obj2; x:x(参数表1):obj2(参数表2),obj1(参数表3) ; main() x a; /构造函数调用顺序:类1=类2=x /析构函数调用顺序:x=类2=类1,对象成员,成员初始化列表,七、其他数据成员,所有数据成员的初始化都可以在成员初始化列表中进行。 const成员、引用成员的初始化必须通过成员初始化列表完成。 参见p57.cpp,第四章 继承和派生类,一、基本概念,类的派生:通过特殊化已有的类建立新类的过程。 基类(父类):已有的类。 派生类(子类):新建立的类。 继承表示类属关系,而不是构成关系。,派生类直接拥有基类的所有成员 派生类可以增加新成员 派生类可以重新定义基类的成员函数 派生类可以改变现有成员的属性,二、继承的属性,性质扩展,性质约束,构造函数和析构函数不被继承,三、继承的分类,单一继承 多重继承,输入设备,输出设备,输入/输出设备,人,教师,学生,(单一继承),(多重继承),四、单一继承,class 派生类名:访问控制 基类名 ;,public private protected,单一继承举例,class point int x,y; public: void show(); ;,class rect:public point int w,h; public: void show() point:show();coutw“,”hendl; int area(); ;,五、保护成员,兼有私有成员和公有成员双重角色。 基类的保护成员可以在派生类内部访问。,保护成员举例,class point protected: int x,y; public: void show(); ;,class rect:public point int w,h; public: void show() coutx“,”y “,”w“,”hendl; int area(); ;,六、公有派生,基类公有成员派生类公有成员 基类保护成员派生类保护成员 基类私有/不可访问成员派生类不可访问成员,公有派生赋值兼容规则,派生类对象可以赋给基类对象 派生类对象可以初始化基类引用 派生类对象地址可以赋给基类指针 rect r; p = r; point p; ptr = 注:ptr, pref只能访问point类的成员。,七、保护派生,基类公有成员派生类保护成员 基类保护成员派生类保护成员 基类私有/不可访问成员派生类不可访问成员,八、私有派生,基类公有成员派生类私有成员 基类保护成员派生类私有成员 基类私有/不可访问成员派生类不可访问成员,派生总结,派生 权限,基类 成员权限,public,protected,private,类内,类外,类内,类外,类内,类外,public,protected,private,派生类内,举例,参见p70.cpp,九、多重继承,class 派生类名:访问控制 基类名1, 访问控制 基类名2 ;,public private protected,基类互不相同,多重继承举例,参见p71.cpp,十、构造函数与析构函数调用顺序,需要由派生类构造函数调用基类构造函数,完成基类成员的初始化。 在成员初始化列表中实现。 构造函数调用顺序: 基类派生类对象成员派生类 析构函数调用顺序: 基类派生类对象成员派生类,构造/析构函数调用举例,参见p73.cpp 参见p74.cpp,十一、两义性及支配规则,两义性对一个名字的访问不确定。 两义性检查先于访问权限,所以访问权限不能解决两义性问题。,两义性举例,class a public: int i; ; class b public: int i; ;,class c:public a,public b public: void show() coutiendl; ;,两义性及支配规则(续),类y是类x的基类,则类x中的名字n支配类y中同名字的n支配规则。 被支配的名字在使用时必须做成员名限定(作用域分辨)。,支配规则举例,class a public: int i; ; class b public: int i; ;,class c:public a,public b public: int i; void show() coutia:i b:i endl; ;,支配规则举例,参见p76.cpp 参见p78.cpp,十二、虚基类,指定派生类的基类时,加关键字virtual将基类说明成虚基类。 派生类可以有多个虚基类。 虚基类使得多重继承路径中的公共基类只产生一个实例。,虚基类举例,class a public: int i; ; class b:virtual public a ; class c:public virtual a ;,class d:public b, public c ; d obj; obj.iobj.a:i obj.b:iobj.c:i,虚基类说明,虚基类指针/引用不能转换为派生类。 派生类构造函数需要显式调用虚基类的构造函数。,虚基类举例,参见p81.cpp,第五章 多态性和虚函数,一、基本概念,多态性:又称为约束、动态约束,主要指函数调用的多态性。 分类 编译时的多态性:函数重载 运行时的多态性:继承和虚函数,静态联编 速度快,动态联编 速度慢,class squared public: int squ(int k)return k*k; double squ(double k) return k*k; ; main() squared obj; coutobj.squ(2)obj.squ(2.5)endl; ,二、静态联编,三、动态联编,参见p90.cpp,四、虚函数,函数声明前加virtual class a virtual void func(); ; void a:func() ,虚函数说明,只能是类中的非静态成员函数 派生类中和基类完全相同的函数,如果基类中是虚函数,派生类中的自动为虚函数 可以通过成员名限定强制使用静态联编 派生类中定义的虚函数的访问权限不影响动态联编 构造/析构函数中调用虚函数采用静态联编,虚函数举例,参见p92.cpp 参见p93.cpp 参见p95.cpp,五、纯虚函数和抽象类,纯虚函数:不需要提供函数的实现代码。 class 类名 virtual 返回值类型 函数名(参数列表)=0; ; 抽象类:包含纯虚函数的类。,纯虚函数和抽象类说明,一个类可以有多个纯虚函数。 抽象类至少有一个纯虚函数。 抽象类只能作为基类派生新类,不能实例化对象,但可以说明指向抽象类对象的指针。 抽象类的派生类必须提供纯虚函数的实现代码,或者继续将它说明为纯虚函数。 成员函数可以调用纯虚函数,但构造/析构函数中不行。,纯虚函数和抽象类举例,参见p97.cpp 参见p98.cpp 参见p100.cpp 参见p101.cpp,六、虚析构函数,虚析构函数的调用采用动态联编。 如果基类的析构函数为虚函数,则派生类的析构函数自动为虚函数。,虚析构函数举例,参见p103.cpp 参见p95.cpp,第六章 进一步使用成员函数 202.106.114.223/zk/,6.1 静态成员,静态变量 静态对象 静态成员,一、静态变量,只初始化一次 main() for(int i=0;i3;i+) static int n=0; n+; coutnendl; ,输出: 1 2 3,二、静态对象,实例化对象时加static 例如:假定a为一个类, static a a; 则a为一个静态对象。,静态对象举例,参见pmy1.cpp,三、静态成员,class a static int x; public: static int getx(); int a:getx() return x;,静态成员说明,静态成员为类所有对象共享 不需要实例化对象,静态成员就存在,可用成员名限定直接访问 静态成员函数没有this指针 静态成员可以被继承,所有基类和派生类对象共享该成员 静态成员的初始化不能在成员初始化列表中进行,静态成员说明(续),为保证封装性,一般将静态数据成员定义为private,然后定义public的静态成员函数对其访问 静态成员函数不能是虚函数 静态数据成员只是一个引用性说明,必须在类定义外给出定义性说明,静态成员举例,参见pmy2.cpp,6.2 const成员,const变量 const对象 const成员,一、 const变量,值不能被修改 main() const int i=10; i=20; /错 int j = 30; const int* p1 = /错 ,实例化对象时加const 例如:假定a为一个类, const a a; 则a为一个const对象。 const对象的值不能被修改 const对象只能访问const成员函数,二、const对象,const对象举例,class a public: int n; a(int k) n = k; int getn() return n; ; void main() const a a(10); a.n = 20; /错,a的值不能被修改 couta.getn(); /错,a只能访问const成员函数 ,const数据成员必须在成员初始化列表中被初始化 const成员函数 定义:int fun() const; 实现时const也必须加 成员函数中的this指针及其所指向的内容都是const的,即不能在const成员函数中修改数据成员的值 构造/析构函数不能加const,三、const成员,const 类名* const this;,const成员举例,参见pmy3.cpp,6.3 友元,类的友元可以访问类中的所有成员 友元破坏了封装,但提高了程序效率 友元函数 友元类,一、友元函数,在类中声明,声明前加friend class point int x,y; friend void show(point,友元函数说明,友元函数可以是成员函数,也可以不是,如果不是就没有this指针 友元函数与访问控制权限没关系,友元函数举例,参见pmy4.cpp 参见pmy5.cpp,二、友元类,如果类a是类b的友元,则类a的所有成员函数都可以访问b类的所有成员。,友元类举例,参见pmy6.cpp,三、友元和派生类,友元关系不能继承,也不能交换 派生类的友元可以访问直接基类的公有、保护成员,友元和派生类举例,参见pmy7.cpp,6.4 转换函数,operator type(); 转换函数实现从类到type的类型转换 转换函数可以被派生类继承 转换函数可以是虚函数,基本类型、指针、数组、函数,转换函数举例,参见p118.cpp,6.5 指向类成员的指针,指向类数据成员的指针 指向类成员函数的指针,一、指向类数据成员的指针,定义指向类x中类型为type的数据成员的指针变量: type x:* 指针变量名; 使该指针变量指向类x中类型为type的数据成员member: 指针变量名= 如果指向静态成员,被访问时不需要对象。,二、指向类成员函数的指针,定义指向类x中返回值类型为type,参数列表为list的成员函数的指针变量: type (x:* 指针变量名) (list); 使该指针变量指向类x中返回值类型为type,参数列表为list的成员函数func: 指针变量名=x:func; 如果指向虚函数,被访问时仍发生多态性。,指向类成员的指针举例,参见p121.cpp,6.6 数组和类,类对象数组 类对象指针数组 类数据成员指针数组 类成员函数指针数组,数组和类举例,参见pmy8.cpp,第七章 运算符重载及流类库,7.1 运算符重载,c+由函数组成,任何运算都通过函数实现。 eg)3+2operator+(int,int) 运算符重载就是函数重载,一、运算符重载函数的定义,类型 operator (参数列表) ,不能为void, 一般为类类型。,运算符,不能为., *, :, ?:,二、运算符重载函数说明,不能定义新的运算符 运算符重载不改变运算符的优先级、结合性、操作数数目,只改变操作数数据类型 运算符重载应该尽量符合运算符的常规含义 运算符重载不可有二义性,运算符重载函数说明(续),运算符重载函数可以被派生类继承 支配规则对于运算符重载函数同样适用 运算符重载函数多数可以被说明成虚函数,7.2 类运算符和友元运算符,类运算符:运算符重载函数作为类的成员函数。 友元运算符:运算符重载函数作为类的友元函数。,一、类运算符,单目运算符 运算符重载函数形式: 返回类型 类名:operator() 实际使用形式: objobj.operator() eg)+objobj.operator+(),类运算符(续),双目运算符 运算符重载函数形式: 返回类型 类名:operator(obj2) 实际使用形式: obj1obj2obj1.operator(obj2) eg)obj1+obj2 obj1.operator+(obj2),二、友元运算符,单目运算符 运算符重载函数形式: friend 返回类型 operator(类名& obj) 实际使用形式: objoperator(obj) eg)+objoperator+(obj),友元运算符(续),双目运算符 运算符重载函数形式: friend 返回类型 operator(类名& obj1,类名& obj2) 实际使用形式: obj1obj2operator(obj1,obj2) eg)obj1+obj2 operator+(obj1,obj2),类运算符和友元运算符说明,如果运算符的第一个操作数需要做隐式类型转换,一般用友元运算符重载(双目) 如果需要修改类对象的状态,一般用类运算符(单目) =、()、-只能用类运算符,类运算符和友元运算符举例,参见p130.cpp 参见pmy9.cpp 参见pmy10.cpp,7.3 +、-运算符的重载,类运算符 objobj.operator() objobj.operator(0)obj0 友元运算符 objoperator(obj) objoperator(obj,0)obj0,+、-运算符的重载举例,参见p133.cpp 参见p134.cpp,7.4 流类库,流类:执行输入输出操作的类体系 流类库:提供流类实现的系统库,一、流类库的类等级,ios,istream,ostream,iostream,streambuf,二、流类库预定义的四个流,cin:标准输入设备 cout:标准输出设备 cerr:标准错误输出设备(非缓冲方式) clog:标准错误输出设备(缓冲方式),7.5 运算符的重载,ostream ,运算符的重载举例,参见p137.cpp,7.6 格式控制,iso类提供的接口 内部格式控制函数,一、iso类提供的接口,iostream.h中定义的iso类实现 iso类通过设置格式标志实现格式控制 格式标志存放在iso类的长整型成员中,每个标志占一位,二、内部格式控制函数,iomanip.h中定义 可以通过设置格式标志实现格式控制,也可以直接设置控制格式 可以把格式控制嵌入到输入输出中间,三、格式控制比较,格式控制举例,参见p139.cpp 参见p140.cpp,7.7 文件操作方式,fstream.h中定义了三种文件流

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论