第5章 类和对象.ppt_第1页
第5章 类和对象.ppt_第2页
第5章 类和对象.ppt_第3页
第5章 类和对象.ppt_第4页
第5章 类和对象.ppt_第5页
已阅读5页,还剩95页未读 继续免费阅读

下载本文档

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

文档简介

第五章类和对象 本章内容 面向对象程序设计概述类的定义对象的定义和对象成员的引用构造函数析构函数this指针静态成员 不讲 友元类模板 不讲 程序设计方法的发展历程 面向过程的程序设计方法SP StructuredProgramming 面向对象的程序设计OOP ObjectOrientedProgramming towardsinrelationtoconcerning 面向过程的程序设计方法 重点以功能为中心 采用函数来描述 数据与函数分开 如何实现细节过程 设计思路特点自顶向下 逐步求精 功能分解 程序结构形式主模块 若干个子模块 main 子函数 每一模块内部均是由顺序 选择和循环三种基本结构组成 缺点效率低 程序的可重用性差 面向过程结构化程序设计 数据1 数据2 数据3 6 两种程序设计方法 面向过程的面向对象的程序设计程序设计 OOP data3 data2 data1 例 计算两个矩形的面积 面向过程的方法 classRect public voidsetXY doublex1 doubley1 l x1 w y1 doublearea returnl w private doublel w voidmain Rectr1 r2 r1 setXY 20 12 5 r2 setXY 25 6 22 6 cout r1 area endl cout r2 area endl 例 计算矩形的面积 面向对象的方法 classRect 矩形的抽象描述 矩形类 public 成员访问权限 矩形的操作方法 成员函数 voidsetXY doublex1 doubley1 接口 l x1 w y1 doublearea returnl w private doublel w 矩形的属性 数据成员 voidmain Rectr1 r2 定义矩形对象r1 setXY 20 12 5 r2 setXY 25 6 22 6 cout r1 area endl cout r2 area endl 例 计算矩形的面积 面向对象的方法 面向对象的程序设计方法 观点 客观世界是由各种各样的实体 对象 组成的 程序设计方法 使用面向对象的观点来描述模仿并处理现实问题 使程序设计方法更符合人类的思维方式 更直接地描述客观世界 要求 高度概括 分类 和抽象 目的 通过提高代码的可重用性 可扩充性来提高编程效率 大大减少软件维护的开销 适合于大程序的开发工作 面向对象的程序设计方法 将数据及对数据的操作方法封装在一起 作为一个相互依存 不可分离的整体 对象 对同类型对象抽象出其共性 形成类 类通过一个简单的外部接口 与外界发生关系 对象与对象之间通过发消息进行通讯 通过类的继承与多态实现代码重用 客观世界 继续抽象 对象 对象 对象 对象 对象 对象 对象 计算机内的对象 面向对象分析与设计 编程 运行 面向对象方法强调充分运用人类在日常逻辑思维中经常采用的思想 方法与原则 例如抽象 继承 聚合 封装等 这使得软件开发者能更有效地思考问题 并以其他人也能看得懂的方式把自己的认识表达出来 比较 BeforeOOP代码联系紧密难于编写和维护难于修改代码可重用性差数据安全性不好小型软件开发效率高 WithOOP程序是由一系列相互协作的对象构成更易于编写和维护修改容易代码可重用性高数据安全性好开发大型软件和图形界面的应用软件效率高 一般意义上的对象 客观世界中的事物都是对象 一个对象是现实世界中一个实际存在的事物 可以是有形的 比如一辆汽车 也可以是无形的 比如一项计划 是构成世界的一个独立单位 具有 静态特征 对象具有的状态 state 可以用某种数据来描述动态特征 对象所表现的行为 behavior action 或具有的功能 思考 WhatwouldaMP3playerobjectbelike 属性 Data 行为 Actions 思考 WhatwouldaMP3playerobjectbelike 属性 Data numberofsongscurrentsongpowerlevelsongs行为 Actions playpauserewindforwardon off 面向对象方法中的对象 是系统中用来描述客观事物的一个实体 它是用来构成系统的一个基本单位 对象由一组属性和一组行为构成 属性 用来描述事物的数据特征 行为 用来描述事物的行为特征 对象 现实世界对象 现实世界中某一具体的事物静态特征 对象具有的状态动态特征 对象所表现的行为或具有的功能 计算机世界对象 类的一个实例 变量 属性 数据成员操作 方法 由一组函数定义 对象 人 属性 char name char gender intage intid行为 getCloth eat step work 类 分类 人类通常的思维方法分类所依据的原则 抽象忽略事物的非本质特征 只注意那些与当前目标有关的本质特征 从而找出事物的共性 把具有共同性质的事物划分为一类 得出一个抽象的概念 抽象出对象的特征和功能 按此标准对对象分类 面向对象方法中的 类 类是具有相同属性和操作的一类对象的统称 类是对具有相同属性和操作的一组对象的一个抽象描述 包括属性和行为两个部分类定义了这一类对象所共有的特征和行为 Torpie Person 抽象定义 Allen Meijer 抽象实例 人类 JClark Person name gender age id getCloth eat step work 类名 方法 属性 类与对象的关系 对象的抽象定义 描述 每个对象都视为该类的一个实例 instance 类是抽象的 对象是具体的类是模型 对象是实例类是类型 对象是变量 面向对象程序设计方法的基本特征 抽象性封装性继承性多态性 封装 什么是封装为什么要封装如何封装 面向对象语言的特点 封装性 信息隐藏 把对象的属性和服务结合为一体 成为一个独立 不可分的实体 尽可能隐蔽对象的内部细节 对外形成一个边界 或者说一道屏障 只保留有限的对外接口使之与外部发生联系 类的定义 类声明形式 class类名称 public 公有成员 外部接口 private 私有成员protected 保护型成员 私有成员只能被本类中的成员函数访问 而在类的外部不能访问 公有成员作为对外的接口 在类的外部可以访问 保护成员与private类似 其差别表现在继承与派生时对派生类的影响不同 矩形类的定义 classRect public 矩形的操作方法voidsetXY floatx1 floaty1 成员函数原型说明floatarea 成员函数原型说明floatgetX returnx 取长floatgetY returny 取宽private floatx y 矩形的属性 长和宽 voidRect setXY floatx1 floaty1 x x1 y y1 floatRect area returnx y 成员函数 数据成员 内联成员函数定义 设置长和宽 成员函数定义 classRect public voidsetXY floatx1 floaty1 成员函数原型说明floatgetX returnx 内联成员函数定义floatgetY returny 内联成员函数定义floatarea 成员函数原型说明private floatx y inlinevoidRect setXY floatx1 floaty1 x x1 y y1 floatRect area returnx y 矩形类的定义 成员函数 数据成员 数据成员 与一般的变量声明相同 但需要将它放在类的声明体中 成员函数 类的成员函数的定义可以在类体内也可以在类体外 若在体外 需在函数名前加类名和作用域分辨符 加以限定在类体内定义的成员函数将被自动处理为内联函数无需加关键字inline 而要使得在类体外定义的成员函数成为内联函数时 就必须使用inline关键字 讨论 通常把类的数据成员定义为私有 并通过公有成员函数 接口函数 对它们进行访问 定义类的私有成员可实现数据隐藏 而数据隐藏对维护对象的完整性是必不可少的 接口函数可以把对数据的存储细节与数据的使用细节分开 我们可以控制数据的存取成员函数是public 用于使类外用户访问私有数据成员 接口函数 对象的定义 对象类是一种用户自定义的数据类型 这种数据类型的变量称为该类的对象 对象的定义格式 类名对象名表 例 Rectob1 ob1是Rect类的对象 对象成员的引用 类内 类成员可以由类的所有成员函数直接访问 直接使用成员名类外使用 对象名 成员名 方式访问public属性的成员如 ob1 area 称为成员选择运算符 矩形类及其对象的使用 classRect public voidsetXY floatx1 floaty1 x x1 y y1 floatarea returnx y floatgetX returnx floatgetY returny private floatx y intmain Rectr1 定义矩形类Rect对象r1 setXY 12 5 20 若写r1 x 12 5则错误 cout r1 area endl return0 面向对象语言的特点 封装性 信息隐藏 把对象的属性和服务结合 构成一个不可分割的整体在这个整体中一些成员是私有的 或保护的 尽可能隐蔽对象的内部细节 以防外界的干扰和误操作 在这个整体中一些成员是公有的 它们作为接口提供给外界使用 矩形类及其对象的使用 classRect public voidsetXY floatx1 floaty1 x x1 0 0 x1 将矩形的长和宽设置为合法的值y y1 0 0 y1 floatarea returnx y floatgetX returnx floatgetY returny private floatx y intmain Rectr1 r1 setXY 12 5 20 cout r1 area endl return0 rect h类定义classRect public voidsetXY floatx1 floaty1 成员函数说明floatarea 接口floatgetX 接口floatgetY 接口private floatx y rect cpp 类的内部实现 include rect h voidRect setXY floatx1 floaty1 x x1 0 0 x1 y y1 0 0 y1 floatRect area returnx y floatRect getX returnx floatRect getY returny include include rect h intmain Rectr1 r1 setXY 12 5 20 cout r1 area endl return0 定义对象应注意 必须在定义了类之后 才可以定义类的对象 类定义仅提供该类的类型定义 类是一种由数据和函数组成的数据类型 是抽象的 系统并不会为类分配存储空间 对象才是具体的 只有定义了对象后 运行时系统为对象分配存储空间 包括数据空间和代码空间 生命期结束时 释放空间 Rectr1 r2 r3 例 为对象分配存储空间举例 设已定义了矩形类Rect 同一个类的每个对象都拥有属于自己的数据成员 对象的定义和对象成员的引用 Rectob1 ob2 3 Rect ob1是类Rect的对象 ob2是类Rect的对象数组 rd1是类Rect的对象引用 pd是类Rect的对象指针 例 设已定义了矩形类Rect 对象名 公有成员名ob1 area 对象指针名 公有成员名pd area 对象引用名 公有成员名rd1 area 矩形类及其对象的使用 classRect public voidsetXY floatx1 floaty1 x x1 y y1 floatarea returnx y floatgetX returnx floatgetY returny private floatx y intmain Rectr1 r2 r1 setXY 12 5 20 cout r1 area endl cout r2 area endl 有问题return0 构造函数举例 classRect public Rect floatx1 floaty1 x x1 y y1 构造函数voidsetXY floatx1 floaty1 x x1 y y1 floatarea returnx y private floatx y intmain Rectr1 12 5 20 调用构造函数将x y初始化为12 5和50cout r1 area endl r1 setXY 5 2 6 8 调用setXY成员函数重新设置x y的值cout r1 area endl return0 构造函数 构造函数构造函数是类的特殊成员函数 用于对对象的私有数据成员进行初始化 构造函数的特点是 构造函数名必须和本类类名相同 构造函数不允许有任何返回类型 void也不能有 构造函数的参数个数可以为0 也可以有多个 故构造函数可以重载 遇到对象定义时自动调用构造函数 每个类至少有一个构造函数 构造函数 C 规定 如果一个类没有提供任何的构造函数 则C 提供一个默认的构造函数 由C 编译器提供 这个默认的构造函数是一个不带参数的构造函数 它不做任何的初始化工作 只要一个类定义了一个构造函数 不管这个构造函数是否是带参数的构造函数 C 就不再提供默认的构造函数 也就是说 如果为一个类定义了一个带参数的构造函数 还想要无参数的构造函数 则必须自己定义 构造函数举例 classRect public Rect floatx1 floaty1 x x1 y y1 构造函数voidsetXY floatx1 floaty1 x x1 y y1 floatarea returnx y private floatx y intmain Rectr1 12 5 20 调用构造函数将x y初始化为12 5和50cout r1 area endl Rectr2 调用Rect 但类中没有定义Rect 出错cout r2 area endl return0 构造函数重载 classRect public Rect floatx1 floaty1 x x1 y y1 构造函数Rect x 5 y 3 默认构造函数voidsetXY floatx1 floaty1 x x1 y y1 floatarea returnx y private floatx y intmain Rectr1 12 5 20 调用构造函数将x y初始化为12 5和50cout r1 area endl Rectr2 默认构造函数Rect cout r2 area endl return0 构造函数重载 classRect public 需要几个构造函数 floatarea returnx y private floatx y intmain Rectr1 Rectr2 12 5 Rectr3 20 15 return0 构造函数重载 classRect public Rect x 5 y 3 默认构造函数Rect floatx1 x x1 y 10 Rect floatx1 floaty1 x x1 y y1 floatarea returnx y private floatx y intmain Rectr1 调用Rect Rectr2 12 5 调用构造函数Rect floatx1 Rectr3 20 15 调用Rect floatx1 floaty1 return0 参数带默认值的构造函数 classRect public Rect floatx1 10 5 floaty1 5 2 x x1 y y1 floatarea returnx y private floatx y intmain Rectr1 调用Rect Rectr2 12 5 调用构造函数Rect floatx1 Rectr3 20 15 调用Rect floatx1 floaty1 return0 classRect public Rect Rect floatx1 floaty1 voidprint private floatx y Rect Rect floatx1 floaty1 x x1 y y1 Rect Rect x 15 y 12 voidRect print cout x y endl voidmain Rectr1 Rectr2 30 15 r1 print r2 print 关于构造函数的讨论 构造函数的作用就是初始化对象没有形参或形参都有缺省值的构造函数称为默认构造函数构造函数由系统在创建对象时自动调用调用时机为 遇到对象定义时自动调用合适的构造函数遇到new类名或new类名 长度 时自动调用默认构造函数构造函数应定义为公有成员 voidmain Dated1 调用Date Dated2 2007 7 1 调用Date int int int Dated3 5 调用5次Date Date p1 p2 不调用构造函数p1 newDate 2007 11 27 调用Date int int int p2 newDate 4 调用四次Date 析构函数 析构函数析构函数是类的特殊成员函数 完成对象被释放前的一些清理工作 析构函数的特点是 析构函数名为本类类名前加一个 符号析构函数不允许有任何返回类型析构函数不允许带参数 一个类中只能有一个析构函数 即不能重载析构函数如果程序中未定义析构函数 编译程序将自动提供一个函数体为空的默认析构函数 什么时候调析构函数 在对象的生存期结束时 自动调用析构函数 voidmain Rectr1 Rectr2 15 10 调用析构函数 析构函数的调用 析构函数的调用顺序通常是与构造函数的调用顺序相反的 即先构造的后析构 后构造的先析构 要注意 对象的生存期会改变析构函数的调用顺序 构造函数和析构函数 intmain Dated1 Dated2 2007 7 1 p1 newDate 2007 11 27 p2 newDate 4 deletep1 调用析构函数delete p2 调用析构函数return0 调用析构函数 析构函数的调用 classProduct charname 20 floatprice public Product char n floatp voidprint cout name price endl Product Product char n floatp strcpy name n price p cout 调用构造函数 endl intmain Productp1 电视机 2350 p1 print return0 例 析构函数应用举例 调用构造函数电视机2350 程序运行结果 name 电 视 机 0 2350 price p1 运行 classProduct char name floatprice public Product char n floatp Product voidprint cout name price endl Product Product char n floatp 申请堆空间name newchar strlen n 1 strcpy name n price p cout 调用构造函数 endl Product Product if name delete name 释放堆空间name 0 cout 调用析构函数 endl intmain Productp1 电视机 2350 p1 print return0 例 析构函数应用举例 调用构造函数电视机2350调用析构函数 程序运行结果 思考 wehavethefollowingcode Product Product char n floatp name newchar strlen n 1 strcpy name n price p Q Whathappenswhenthemainfunctionfinishes p1 Productp1 电视机 2350 思考 Q 如果没有定义析构函数 当主函数完成后会发生什么 A 变量name被释放 因此不能访问动态内存 造成动态内存泄露 思考 定义一个析构函数 释放动态内存空间Product Product if name delete name 释放动态内存空间name 0 思考 voidmain Productp1 电视机 2350 p1 Print 析构函数被自动调用 关于析构函数的说明 析构函数的作用正好与构造函数相反 在对象生存期结束时自动调用析构函数 如果在构造函数中用new运算符为对象的成员分配了内存空间 堆内存 应该在类中定义析构函数 用delete释放申请的空间 否则 可能会出现内存泄漏 若用户没有定义析构函数 编译程序将自动生成一个函数体为空的析构函数 拷贝构造函数 拷贝构造函数是一种特殊的构造函数 其形参为本类的对象引用 作用 用一个已定义的对象初始化一个被创建的同类对象 class类名 public 类名 形参 构造函数类名 类名 对象名 拷贝构造函数 拷贝构造函数 如果程序员没有为类定义拷贝构造函数 则编译器自己生成一个默认的拷贝构造函数 这个构造函数的功能是 把已定义对象的每个数据成员的值复制给新创建对象的对应数据成员 即实现数据成员的复制 拷贝构造函数 拷贝构造函数由系统自动调用 拷贝构造函数的调用时机 用一个已定义的对象初始化一个新的同类对象在调用一个函数时 把对象作为函数实参传递给函数形参对象作为函数返回值 拷贝构造函数 用一个已定义的对象初始化一个新的同类对象 classPoint private floatx y 点的坐标public Point floatx1 0 floaty1 0 x x1 y y1 voidmain Pointp1 5 6 Pointp2 p1 用p1初始化p2 系统提供的默认拷贝构造函数Point constPoint 拷贝构造函数 当对象作为一个函数实参传递给函数形参 值传递 当对象作为函数返回值 Pointfun Pointp returnp 用p初始化临时对象 voidmain Pointp1 5 6 p2 p2 fun p1 用p1初始化形参p 调用Point p1 调用Point p this指针 this指针是一个隐含于每个类的成员函数中的特殊指针 它指向当前调用成员函数的对象 称为当前对象 代表了当前对象的地址 this指针 一个类所有的对象调用的成员函数都是同一代码段 那么成员函数又是怎么识别属于同一对象的数据成员呢 原来 在对象调用t1 print 时 成员函数接受到了一个对象t1的地址 这个地址被一个隐含的形参this指针所获取 它等同于执行this this指针 classTest intx public Test inta 0 x a voidprint cout x endl intmain Testt1 12 t2 20 t1 print t2 print return0 每次成员函数存取数据成员时 隐含使用this指针 即通常不显式地使用this指针来引用数据成员 this print 例 计算两点间距离 运行 classPoint doublex y public Point doublea 0 doubleb 0 x a y b cout 构造点 x y n voidprint cout 点 x y doubledistance Point intmain Pointob1 ob2 3 4 ob1 print cout 到 ob2 print cout 的距离 cout ob1 distance ob2 cout endl return0 静态成员 静态成员静态成员是属于类的所有对象 而不是某一个对象的成员 静态成员包括静态数据成员和静态成员函数 即使没定义对象 静态成员依然存在 静态成员可以是私有也可以是公有 静态成员Static 静态成员属于类 而不属于对象 用于在对象间共享信息 classFoo intx y staticintf x 0y 0 x 3y 6 x 0y 4 x 8y 6 使用类创建一些对象 classFoof 0 静态成员 静态数据成员静态数据成员必须在类体内说明 并且必须在类体和函数之外定义一次 静态数据成员的说明 static类型名静态数据成员名 类体内 静态数据成员的定义 类型类名 静态数据成员 缺省初始值为0类型类名 静态数据成员 初始值 类体外 例 静态数据成员的使用示例 记录对象的个数 程序运行结果 classCounter private intobjno 对象序号staticintcount 静态数据成员 对象计数器public Counter count 每创建一个对象 对象数加1objno count 设置当前对象序号值 Counter count voidshow cout count count endl intCounter count 0 静态数据成员的定义 intmain Counterobj1 obj1 show Counter pc pc newCounter pc show deletepc obj1 show return0 count 1count 2count 1 静态成员函数 静态成员函数静态成员函数没有this指针 一般使用静态成员函数来访问静态数据成员 若需要在静态成员函数中访问非静态数据成员 则要使用对象参数 静态成员函数的定义 只需在成员函数前加static 对公有的静态成员函数 可用以下形式调用 对象名 静态成员函数名 实参表 类名 静态成员函数名 实参表 例 静态成员函数的使用示例 记录对象的个数 程序运行结果 classCounter private intobjno 对象序号staticintcount 静态数据成员说明public Counter count objno count Counter count staticvoidshow cout count count endl intCounter count 0 静态数据成员的定义 intmain Counter show Counterobj1 Counter show obj1 show Counter pc pc newCounter Counter show pc show obj1 show deletepc Counter show return0 count 0count 1count 2count 1 例 在静态成员函数的使用静态数据成员和非静态数据成员 count 1objno 1 程序运行结果 友元 友元是C 提供的一种破坏数据封装和数据隐藏的机制 通过将一个模块声明为另一个模块的友元 一个模块能够引用到另一个模块中本是被隐藏的信息 可以使用友元函数和友元类 为了确保数据的完整性 及数据封装与隐藏的原则 建议尽量不使用或少使用友元 友元函数 友元函数是在类声明中由关键字friend修饰说明的非成员函数 可以是一个普通函数 也可以是其他类的一个成员函数 类的友元函数只能通过该类的对象访问该类的私有 private 成员和保护 protected 成员 作用 增加灵活性 使程序员可以在封装和快速性方面做合理选择 友元函数 把普通函数说明为友元的格式为 friend类型函数名 形参表 把其它类的成员函数说明为友元的格式为 friend类型类名 函数名 形参表 友元函数的说明必须在类体中给出

温馨提示

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

最新文档

评论

0/150

提交评论