第10部分创建功能强的类型

上传人:仙*** 文档编号:43579467 上传时间:2021-12-03 格式:PPT 页数:120 大小:284KB
收藏 版权申诉 举报 下载
第10部分创建功能强的类型_第1页
第1页 / 共120页
第10部分创建功能强的类型_第2页
第2页 / 共120页
第10部分创建功能强的类型_第3页
第3页 / 共120页
资源描述:

《第10部分创建功能强的类型》由会员分享,可在线阅读,更多相关《第10部分创建功能强的类型(120页珍藏版)》请在装配图网上搜索。

1、程序设计 cs.sjtu 2011.9程序设计 - 1v从面向过程到面向对象从面向过程到面向对象 v类的定义类的定义 v对象的使用对象的使用v对象的构造与析构对象的构造与析构 v常量对象与常量对象与const成员函数成员函数 v常量数据成员常量数据成员 v静态数据成员与静态成员函数静态数据成员与静态成员函数 v友元友元 程序设计 cs.sjtu 2011.9程序设计 - 2v抽象的过程抽象的过程 v面向对象的程序设计的特点面向对象的程序设计的特点 v库和类库和类 程序设计 cs.sjtu 2011.9程序设计 - 3v计算机的工作是建立在抽象的基础上。计算机的工作是建立在抽象的基础上。机器语言

2、和汇编语言是对机器硬件的抽象机器语言和汇编语言是对机器硬件的抽象高级语言是对汇编语言和机器语言的抽象高级语言是对汇编语言和机器语言的抽象v现有抽象的问题:现有抽象的问题:要求程序员按计算机的结构去思考,而不是按要解决要求程序员按计算机的结构去思考,而不是按要解决的问题的结构去思考。的问题的结构去思考。 当程序员要解决一个问题时,必须要在机器模型和实当程序员要解决一个问题时,必须要在机器模型和实际要解决的问题模型之间建立联系。际要解决的问题模型之间建立联系。而计算机的结构本质上还是为了支持计算,当要解决而计算机的结构本质上还是为了支持计算,当要解决一些非计算问题时,这个联系的建立是很困难的一些非

3、计算问题时,这个联系的建立是很困难的 程序设计 cs.sjtu 2011.9程序设计 - 4v为程序员提供了创建工具的功能为程序员提供了创建工具的功能 v解决一个问题时解决一个问题时程序员首先考虑的是需要哪些工具程序员首先考虑的是需要哪些工具创建这些工具创建这些工具用这些工具解决问题用这些工具解决问题v工具就是所谓的对象工具就是所谓的对象v现有的高级语言提供的工具都是数值计现有的高级语言提供的工具都是数值计算的工具算的工具 程序设计 cs.sjtu 2011.9程序设计 - 5v过程化的设计方法:从功能和过程着手过程化的设计方法:从功能和过程着手输入圆的半径或直径输入圆的半径或直径利用利用S=

4、r2和和C=2r计算面积和周长计算面积和周长输出计算结果输出计算结果 v面向对象的程序设计方法:面向对象的程序设计方法:需要什么工具。如果计算机能提供给我们一个称为圆的需要什么工具。如果计算机能提供给我们一个称为圆的工具,它可以以某种方式保存一个圆,告诉我们有关这工具,它可以以某种方式保存一个圆,告诉我们有关这个圆的一些特性,如它的半径、直径、面积和周长。个圆的一些特性,如它的半径、直径、面积和周长。定义一个圆类型的变量,以他提供的方式将一个圆保存定义一个圆类型的变量,以他提供的方式将一个圆保存在该变量中,然后让这个变量告诉我们这个圆的面积和在该变量中,然后让这个变量告诉我们这个圆的面积和周长

5、是多少周长是多少 以计算圆的面积和周长的问题为例以计算圆的面积和周长的问题为例程序设计 cs.sjtu 2011.9程序设计 - 6v抽象的过程抽象的过程 v面向对象的程序设计的特点面向对象的程序设计的特点 v库和类库和类 程序设计 cs.sjtu 2011.9程序设计 - 7v代码重用:圆类型也可以被那些也需要处代码重用:圆类型也可以被那些也需要处理圆的其他程序员使用理圆的其他程序员使用 v实现隐藏:实现隐藏:类的创建者创造新的工具类的创建者创造新的工具类的使用者则收集已有的工具快速解决所需解类的使用者则收集已有的工具快速解决所需解决的问题决的问题这些工具是如何实现的,类的使用者不需要知这些

6、工具是如何实现的,类的使用者不需要知道道 程序设计 cs.sjtu 2011.9程序设计 - 8v继承:在已有工具的基础上加以扩展,形成一个功能继承:在已有工具的基础上加以扩展,形成一个功能更强的工具。如在学校管理系统中,可以形成如下的更强的工具。如在学校管理系统中,可以形成如下的继承关系继承关系 人人教师教师学生学生教辅教辅高级高级中级中级初级初级本科本科硕士硕士博士博士实验室实验室行政行政程序设计 cs.sjtu 2011.9程序设计 - 9v多态性:多态性:当处理层次结构的类型时,程序员往往想把各个层次的当处理层次结构的类型时,程序员往往想把各个层次的对象都看成是基类成员。对象都看成是基

7、类成员。如需要对教师进行考核,不必管他是什么职称,只要向如需要对教师进行考核,不必管他是什么职称,只要向所有教师发一个考核指令。每位教师自会按照自己的类所有教师发一个考核指令。每位教师自会按照自己的类型作出相应的处理。如高级职称的教师会按高级职称的型作出相应的处理。如高级职称的教师会按高级职称的标准进行考核,初级职称的教师会按初级职称的标准进标准进行考核,初级职称的教师会按初级职称的标准进行考核。行考核。v好处:程序代码就可以不受新增类型的影响。如增加一个好处:程序代码就可以不受新增类型的影响。如增加一个院士的类型,它也是教师类的一个子类,整个程序不用修院士的类型,它也是教师类的一个子类,整个

8、程序不用修改,但功能得到了扩展。改,但功能得到了扩展。程序设计 cs.sjtu 2011.9程序设计 - 10v抽象的过程抽象的过程 v面向对象的程序设计的特点面向对象的程序设计的特点 v库和类库和类 程序设计 cs.sjtu 2011.9程序设计 - 11v类是更合理的库类是更合理的库 v例:设计一个库,提供动态实型数组服例:设计一个库,提供动态实型数组服务,该数组满足两个要求:务,该数组满足两个要求:可以任意指定下标范围;可以任意指定下标范围;下标范围可在运行时确定;下标范围可在运行时确定;使用下标变量时会检查下标的越界。使用下标变量时会检查下标的越界。程序设计 cs.sjtu 2011.

9、9程序设计 - 12v数组的保存数组的保存数组需要一块保存数组元素的空间。这块空间需数组需要一块保存数组元素的空间。这块空间需要在执行时动态分配。要在执行时动态分配。数组的下标可以由用户指定范围。因此,对每个数组的下标可以由用户指定范围。因此,对每个数组还需要保存下标的上下界。数组还需要保存下标的上下界。保存这个数组的三个部分是一个有机的整体,因保存这个数组的三个部分是一个有机的整体,因此可以用一个结构体把它们封装在一起。此可以用一个结构体把它们封装在一起。v数组操作数组操作给数组分配空间给数组分配空间给数组元素赋值给数组元素赋值取某一个数组元素的值取某一个数组元素的值由于这个数组的存储空间是

10、动态分配的,因此,由于这个数组的存储空间是动态分配的,因此,还必须有一个函数去释放空间还必须有一个函数去释放空间 程序设计 cs.sjtu 2011.9程序设计 - 13#ifndef _array_h#define _array_h/可指定下标范围的数组的存储struct DoubleArray int low; int high; double *storage;程序设计 cs.sjtu 2011.9程序设计 - 14/根据根据low和和high为数组分配空间为数组分配空间bool initialize(DoubleArray &arr, int low, int high);/设置数组元

11、素的值设置数组元素的值bool insert(const DoubleArray &arr, int index, double value);/取数组元素的值取数组元素的值bool fatch(const DoubleArray &arr, int index, double &value);/回收数组空间回收数组空间void cleanup(const DoubleArray &arr);#endif 程序设计 cs.sjtu 2011.9程序设计 - 15#include array.h#include using namespace std;bool initialize(Double

12、Array &arr, int low, int high) arr.low = low; arr.high = high; arr.storage = new double high - low + 1; if (arr.storage = NULL) return false; else return true;程序设计 cs.sjtu 2011.9程序设计 - 16bool insert(const DoubleArray &arr, int index, double value) if (index arr.high) return false; arr.storageindex -

13、 arr.low = value; return true;bool fatch(const DoubleArray &arr, int index, double &value) if (index arr.high) return false; value = arr.storageindex - arr.low ; return true;void cleanup(const DoubleArray &arr) delete arr.storage; 程序设计 cs.sjtu 2011.9程序设计 - 17#include using namespace std;#include arr

14、ay.h int main() DoubleArray array; double value; int low, high, i; cout low high; if (!initialize(array, low, high) cout 空间分配失败空间分配失败 ; return 1; 程序设计 cs.sjtu 2011.9程序设计 - 18for (i = low; i = high; +i) cout 请输入第请输入第 i value; insert(array, i, value); while (true) cout i; if (i = 0) break; if (fatch(a

15、rray, i, value) cout value endl; else cout 下标越界下标越界n; cleanup(array); return 0; 程序设计 cs.sjtu 2011.9程序设计 - 19v这个数组的使用相当笨拙。每次调用和数组有关的函数这个数组的使用相当笨拙。每次调用和数组有关的函数时,都要传递一个结构体给它。时,都要传递一个结构体给它。v我们可能在一个程序中用到很多库,每个库都可能需要我们可能在一个程序中用到很多库,每个库都可能需要做初始化和清除工作。库的设计者都可能觉得做初始化和清除工作。库的设计者都可能觉得initialize和和cleanup是比较合适的名

16、字,因而都写了这两个函数。是比较合适的名字,因而都写了这两个函数。v系统内置的数组在数组定义时就指定了元素个数,系统系统内置的数组在数组定义时就指定了元素个数,系统自动会根据元素个数为数组准备存储空间。而我们这个自动会根据元素个数为数组准备存储空间。而我们这个数组的下标范围要用数组的下标范围要用initialize函数来指定,比内置数组多函数来指定,比内置数组多了一个操作。了一个操作。v当数组使用结束后,还需要库的用户显式地归还空间。当数组使用结束后,还需要库的用户显式地归还空间。v对数组元素的操作不能直接用下标变量的形式表示。对数组元素的操作不能直接用下标变量的形式表示。 程序设计 cs.s

17、jtu 2011.9程序设计 - 20v将函数放入结构体将函数放入结构体 v好处:好处:函数原型中的第一个参数不再需要。编译函数原型中的第一个参数不再需要。编译器自然知道函数体中涉及到的器自然知道函数体中涉及到的low, high和和storage是同一结构体变量中的成员是同一结构体变量中的成员函数名冲突的问题也得到了解决。现在函函数名冲突的问题也得到了解决。现在函数名是从属于某一结构体,从属于不同结数名是从属于某一结构体,从属于不同结构体的同名函数是不会冲突的。构体的同名函数是不会冲突的。程序设计 cs.sjtu 2011.9程序设计 - 21#ifndef _array_h#define

18、_array_hstruct DoubleArray int low; int high; double *storage; bool initialize(int lh, int rh); bool insert(int index, double value); bool fatch(int index, double &value); void cleanup();#endif 函数都瘦身了!函数都瘦身了!程序设计 cs.sjtu 2011.9程序设计 - 22v与原来的实现有一个变化:函数名前要加与原来的实现有一个变化:函数名前要加限定限定bool IntArray:initializ

19、e(int lh, int rh)low = lh; high = rh; storage = new double high - low + 1; if (storage = NULL) return false; else return true; 程序设计 cs.sjtu 2011.9程序设计 - 23v函数的调用方法不同。就如引用结构体函数的调用方法不同。就如引用结构体的成员一样,要用点运算符引用这些函的成员一样,要用点运算符引用这些函数数 程序设计 cs.sjtu 2011.9程序设计 - 24#include using namespace std;#include array.h

20、“int main() DoubleArray array; double value; int low, high, i; cout low high; if (!array.initialize(low, high) cout 空间分配失败空间分配失败 ; return 1; 程序设计 cs.sjtu 2011.9程序设计 - 25for (i = low; i = high; +i) cout 请输入第请输入第 i value; array.insert(i, value); while (true) /数组元素的查找数组元素的查找 cout i; if (i = 0) break; i

21、f (array.fatch(i, value) cout value endl; else cout 下标越界下标越界n; array.cleanup(); return 0; 程序设计 cs.sjtu 2011.9程序设计 - 26v将函数放入结构体是从将函数放入结构体是从C到到C+的根本改变的根本改变v在在C中,结构体只是将一组相关的数据捆绑了起中,结构体只是将一组相关的数据捆绑了起来,它除了使程序逻辑更加清晰之外,对解决问来,它除了使程序逻辑更加清晰之外,对解决问题没有任何帮助。题没有任何帮助。v将处理这组数据的函数也加入到结构体中,结构将处理这组数据的函数也加入到结构体中,结构体就有

22、了全新的功能。它既能描述属性,也能描体就有了全新的功能。它既能描述属性,也能描述对属性的操作。事实上,它就成为了和内置类述对属性的操作。事实上,它就成为了和内置类型一样的一种全新的数据类型。型一样的一种全新的数据类型。v为了表示这是一种全新的概念,为了表示这是一种全新的概念,C+用了一个新用了一个新的名称的名称 类来表示。类来表示。程序设计 cs.sjtu 2011.9程序设计 - 27v从面向过程到面向对象从面向过程到面向对象 v类的定义类的定义 v对象的使用对象的使用v对象的构造与析构对象的构造与析构 v常量对象与常量对象与const成员函数成员函数 v常量数据成员常量数据成员 v静态数据

23、成员与静态成员函数静态数据成员与静态成员函数 v友元友元 程序设计 cs.sjtu 2011.9程序设计 - 28vclass 类名类名 private: 私有数据成员和成员函数私有数据成员和成员函数 public: 公有数据成员和成员函数公有数据成员和成员函数 ; 程序设计 cs.sjtu 2011.9程序设计 - 29v私有成员私有成员(private):只能由类的成员函:只能由类的成员函数调用数调用v公有成员公有成员(public):类的用户可以调用的:类的用户可以调用的信息,是类对外的接口信息,是类对外的接口v私有成员被封装在一个类中,类的用户私有成员被封装在一个类中,类的用户是看不见

24、的是看不见的程序设计 cs.sjtu 2011.9程序设计 - 30class DoubleArray private: int low; int high; double *storage;public: bool initialize(int lh, int rh); bool insert(int index, double value); bool fatch(int index, double &value); void cleanup();程序设计 cs.sjtu 2011.9程序设计 - 31vprivate 和和public的出现次序可以是任意的的出现次序可以是任意的。也可以反

25、复出现多次。也可以反复出现多次。v成员还可以被说明为成员还可以被说明为protectedv数据成员一般说明为数据成员一般说明为private,需要被用户,需要被用户调用的函数说明为调用的函数说明为public程序设计 cs.sjtu 2011.9程序设计 - 32v与库设计一样,类的定义写在接口文件与库设计一样,类的定义写在接口文件中,成员函数的实现写在实现文件中。中,成员函数的实现写在实现文件中。v某些简单的成员函数的定义可以直接写某些简单的成员函数的定义可以直接写在类定义中。在类定义中。v在类定义中定义的成员函数被认为是内在类定义中定义的成员函数被认为是内联函数。联函数。程序设计 cs.s

26、jtu 2011.9程序设计 - 33v试定义一个有理数类,该类能提供有理试定义一个有理数类,该类能提供有理数的加和乘运算。要求保存的有理数是数的加和乘运算。要求保存的有理数是最简形式。如最简形式。如2/6应记录为应记录为1/3。 程序设计 cs.sjtu 2011.9程序设计 - 34v保存有理数:保存一个有理数就是保存两个整数。保存有理数:保存一个有理数就是保存两个整数。v有理数类的操作:有理数类的操作:加函数加函数乘函数乘函数创建有理数的函数,用以设置有理数的分子和分母创建有理数的函数,用以设置有理数的分子和分母输出有理数函数输出有理数函数化简函数化简函数v访问权限设计:访问权限设计:数

27、据成员是私有的数据成员是私有的化简函数是内部调用的函数,与用户无关,因此也是私有的化简函数是内部调用的函数,与用户无关,因此也是私有的其他函数都是公有的其他函数都是公有的程序设计 cs.sjtu 2011.9程序设计 - 35#ifndef _rational_h#define _rational_h#include using namespace std;class Rational private:int num;int den;void ReductFraction(); /将有理数化简成最简形式将有理数化简成最简形式public:void create(int n, int d) nu

28、m = n; den = d; void add(const Rational &r1, const Rational &r2); void multi(const Rational &r1, const Rational &r2);void display() cout num / den) ? den : num; for (; tmp 1; -tmp) if (num % tmp = 0 & den % tmp =0) num /= tmp; den /= tmp; break;程序设计 cs.sjtu 2011.9程序设计 - 38v从面向过程到面向对象从面向过程到面向对象 v类的定义

29、类的定义 v对象的使用对象的使用v对象的构造与析构对象的构造与析构 v常量对象与常量对象与const成员函数成员函数 v常量数据成员常量数据成员 v静态数据成员与静态成员函数静态数据成员与静态成员函数 v友元友元 程序设计 cs.sjtu 2011.9程序设计 - 39v类与对象的关系:类型与变量的关系类与对象的关系:类型与变量的关系v对象定义方法:对象定义方法:直接在程序中定义某个类的对象直接在程序中定义某个类的对象存储类别存储类别 类名类名 对象列表;对象列表;如定义两个如定义两个IntArrayIntArray类的对象类的对象arr1arr1和和arr2arr2,可写,可写成:成:Int

30、Array arr1, arr2;IntArray arr1, arr2;用动态内存申请的方法申请一个动态对象。用动态内存申请的方法申请一个动态对象。 Rational *rp;Rp = new Rational; rp = new Rational20; delete Rp;或delete rp;程序设计 cs.sjtu 2011.9程序设计 - 40v对象名对象名.数据成员名数据成员名 或或 对象指针对象指针-数据成员名数据成员名 arr1.storage 或或 rp-numv对象名对象名.成员函数名(实际参数表)成员函数名(实际参数表) 或或对象指针对象指针-成员函数名(实际参数表)成员

31、函数名(实际参数表) arr1.insert() 或或 rp-add()v外部函数不能引用对象的私有成员外部函数不能引用对象的私有成员程序设计 cs.sjtu 2011.9程序设计 - 41#include using namespace std;#include Rational.h /使用有理数类使用有理数类int main() int n, d; Rational r1, r2, r3; /定义三个有理数类的对象定义三个有理数类的对象 计算两个有理数的和与积计算两个有理数的和与积 程序设计 cs.sjtu 2011.9程序设计 - 42 cout n d; r1.create(n,d);

32、 cout n d; r2.create(n,d); r3.add(r1, r2); /执行执行r3=r1+r2 r1.display(); cout + ; r2.display(); cout = ; r3.display(); cout endl; r3.multi(r1, r2); /执行执行r3=r1*r2 r1.display(); cout * ; r2.display(); cout = ; r3.display(); cout num = n; this-den = d;程序设计 cs.sjtu 2011.9程序设计 - 46v通常,在写成员函数时可以省略通常,在写成员函数时

33、可以省略this,编译,编译时会自动加上它们。时会自动加上它们。v如果在成员函数中要把对象作为整体来访问如果在成员函数中要把对象作为整体来访问时,必须显式地使用时,必须显式地使用this指针。这种情况常指针。这种情况常出现在函数中返回一个对调用函数的对象的出现在函数中返回一个对调用函数的对象的引用,引用, 程序设计 cs.sjtu 2011.9程序设计 - 47v从面向过程到面向对象从面向过程到面向对象 v类的定义类的定义 v对象的使用对象的使用v对象的构造与析构对象的构造与析构 v常量对象与常量对象与const成员函数成员函数 v常量数据成员常量数据成员 v静态数据成员与静态成员函数静态数据

34、成员与静态成员函数 v友元友元 程序设计 cs.sjtu 2011.9程序设计 - 48v某些类的对象,必须在对它进行了初始化以后某些类的对象,必须在对它进行了初始化以后才能使用。才能使用。v对于某些类的对象在消亡前,往往也需要执行对于某些类的对象在消亡前,往往也需要执行一些操作,做一些善后的处理。一些操作,做一些善后的处理。v初始化和扫尾的工作给类的用户带来了额外的初始化和扫尾的工作给类的用户带来了额外的负担,使他们觉得类和内置类型还是不一样。负担,使他们觉得类和内置类型还是不一样。v用户希望使用类的对象就和使用内置类型的变用户希望使用类的对象就和使用内置类型的变量一样,一旦定义了,就能直接

35、使用。用完了量一样,一旦定义了,就能直接使用。用完了,由系统自动回收。,由系统自动回收。程序设计 cs.sjtu 2011.9程序设计 - 49v构造函数和析构函数是特殊的成员函数构造函数和析构函数是特殊的成员函数v构造函数:对数据成员进行初始化。构造函数:对数据成员进行初始化。v析构函数:执行与构造函数相反的操作析构函数:执行与构造函数相反的操作,通常执行一些清理工作,如释放分配,通常执行一些清理工作,如释放分配给对象的动态空间等。给对象的动态空间等。程序设计 cs.sjtu 2011.9程序设计 - 50v定义对象时,系统会自动调用构造函数。定义对象时,系统会自动调用构造函数。v构造函数的

36、名字必须与类名相同构造函数的名字必须与类名相同v构造函数可以有任意类型的参数,也可以不带参数,但构造函数可以有任意类型的参数,也可以不带参数,但不能具有返回类型。因此在定义构造函数时,不能说明不能具有返回类型。因此在定义构造函数时,不能说明它的类型,甚至说明为它的类型,甚至说明为void类型也不行。类型也不行。v如果没有给类定义构造函数,编译系统会自动生成一个如果没有给类定义构造函数,编译系统会自动生成一个缺省的构造函数。它只为对象开辟存储空间,空间中的缺省的构造函数。它只为对象开辟存储空间,空间中的内容为随机数。内容为随机数。v构造函数可以重载构造函数可以重载程序设计 cs.sjtu 201

37、1.9程序设计 - 51v如如DoubleArray类需要有一个构造函数,该函类需要有一个构造函数,该函数可定义为数可定义为 DoubleArray(int lh, int rh) low = lh; high = rh; storage = new double high low + 1; 有了构造函数,就不需要有了构造函数,就不需要initialize函数了。以函数了。以在定义时有在定义时有C+自动完成初始化工作。自动完成初始化工作。v定义对象时,须指定构造函数的实际参数定义对象时,须指定构造函数的实际参数 DoubleArray array(20, 30);程序设计 cs.sjtu 20

38、11.9程序设计 - 52vRational类不一定要有构造函数,但习惯上应改类不一定要有构造函数,但习惯上应改为每个类定义一个构造函数,以便在需要时对为每个类定义一个构造函数,以便在需要时对对象进行初始化对象进行初始化vRational类构造函数可定义为类构造函数可定义为 Rational(int n1, int n2) num = n1; den = n2; ReductFraction(); v定义对象时,须指定构造函数的实际参数。例定义对象时,须指定构造函数的实际参数。例 Rational r(2, 7);程序设计 cs.sjtu 2011.9程序设计 - 53v有了构造函数后,对象定

39、义的一般形式为:有了构造函数后,对象定义的一般形式为: 类名类名 对象名(实际参数表);对象名(实际参数表); 其中,实际参数表必须和该类的某一个构造其中,实际参数表必须和该类的某一个构造函数的形式参数表相对应。函数的形式参数表相对应。v除非这个类有一个构造函数是没有参数的,除非这个类有一个构造函数是没有参数的,那么可以用:那么可以用: 类名类名 对象名;对象名;v不带参数的构造函数称为默认的构造函数。不带参数的构造函数称为默认的构造函数。v一般每个类应该有一个缺省的构造函数一般每个类应该有一个缺省的构造函数 程序设计 cs.sjtu 2011.9程序设计 - 54vRational(int

40、n1 = 0, int n2 = 1)Rational(int n1 = 0, int n2 = 1) num = n1; den = n2; num = n1; den = n2; ReductFraction(); ReductFraction(); v表示缺省情况下,构造的是一个值为表示缺省情况下,构造的是一个值为0 0的有理数的有理数。此时,定义。此时,定义 Rational r1(3,5), r2;Rational r1(3,5), r2; 是正确的是正确的程序设计 cs.sjtu 2011.9程序设计 - 55v动态变量的初始化是在类型后面用一个圆动态变量的初始化是在类型后面用一个

41、圆括号指出它的实际参数表括号指出它的实际参数表v如果要为一个动态的如果要为一个动态的DoubleArray数组指数组指定下标范围为定下标范围为20到到30,可用下列语句:,可用下列语句: p = new DoubleArray(20, 30);v括号中的实际参数要和构造函数的形式参括号中的实际参数要和构造函数的形式参数表相对应。数表相对应。程序设计 cs.sjtu 2011.9程序设计 - 56v构造函数还有一个与普通函数不同的地方,就是可构造函数还有一个与普通函数不同的地方,就是可以包含一个构造函数初始化列表。以包含一个构造函数初始化列表。v构造函数初始化列表位于函数头和函数体之间。它构造函

42、数初始化列表位于函数头和函数体之间。它以一个冒号开头,接着是一个以逗号分隔的数据成以一个冒号开头,接着是一个以逗号分隔的数据成员构造列表员构造列表v如如DoubleArray的构造函数可写为的构造函数可写为 DoubleArray : DoubleArray(int lh, int rh) : low(lh), high(rh) storage = new double high - low + 1; 程序设计 cs.sjtu 2011.9程序设计 - 57v对象的构造过程:对象的构造过程:执行每一个数据成员的构造函数。如果成员没有出现执行每一个数据成员的构造函数。如果成员没有出现在初始化列表

43、中,执行默认的构造函数,否则按初始在初始化列表中,执行默认的构造函数,否则按初始化列表中列出的实际参数执行对应的构造函数化列表中列出的实际参数执行对应的构造函数执行类的构造函数执行类的构造函数v利用初始化列表可以提高构造函数的效率。在初利用初始化列表可以提高构造函数的效率。在初始化数据成员的同时完成了赋初始的工作。始化数据成员的同时完成了赋初始的工作。我们完全可以在函数体内对数据成员赋初值我们完全可以在函数体内对数据成员赋初值 !程序设计 cs.sjtu 2011.9程序设计 - 58v构造函数可以重载,导致对象可以构造函数可以重载,导致对象可以有多种方式构造有多种方式构造v试设计一个时间转换

44、器,用户可输试设计一个时间转换器,用户可输入秒、分秒或时分秒输出相应的秒入秒、分秒或时分秒输出相应的秒数。数。程序设计 cs.sjtu 2011.9程序设计 - 59#include Using namespace std;class timer int second; public: timer(int t) second = t; timer(int min, int sec) second = 60 * min + sec; timer(int h, int min, int sec) second=sec+60*min+3600*h; int gettime() return seco

45、nd; main()timer a(20), b(1, 20), c(1, 1, 10); cout a.gettime() endl; cout b.gettime() endl; cout c.gettime() endl;程序设计 cs.sjtu 2011.9程序设计 - 60v析构函数在撤销对象时,完成一些善后析构函数在撤销对象时,完成一些善后工作,由编译系统自动调用工作,由编译系统自动调用v析构函数与构造函数名字相同,但它前析构函数与构造函数名字相同,但它前面必须加一个波浪号(面必须加一个波浪号()v析构函数没有参数,没有返回值,也不析构函数没有参数,没有返回值,也不能重载。能重载。

46、v若定义类时没有定义析构函数,编译系若定义类时没有定义析构函数,编译系统会自动生成一个缺省的空析构函数统会自动生成一个缺省的空析构函数程序设计 cs.sjtu 2011.9程序设计 - 61v并不是每个类都必须要有析构函数,如并不是每个类都必须要有析构函数,如Rational类就不需要析构函数。类就不需要析构函数。v一般在构造函数中有动态申请内存的,一般在构造函数中有动态申请内存的,必须有析构函数。如必须有析构函数。如DoubleArray类,必类,必须有析构函数释放须有析构函数释放storage指向的空间。指向的空间。有了析构函数,就不需要有了析构函数,就不需要cleanup函数了函数了程序

47、设计 cs.sjtu 2011.9程序设计 - 62class DoubleArray int low; int high; double *storage;public: DoubleArray(int lh, int rh):low(lh), high(rh) storage = new double high - low + 1; bool insert(int index, double value); bool fatch(int index, double &value); DoubleArray() delete storage; ; 程序设计 cs.sjtu 2011.9程序设

48、计 - 63#include using namespace std;#include DoubleArray.hint main() DoubleArray array(20,30); int i; double value; for (i=20; i=30; +i) cout 请输入第请输入第 i value; array.insert(i, value); while (true) cout i; if (i = 0) break; if (array.fatch(i, value) cout value endl; else cout 下标越界下标越界n; return 0; 程序设计

49、 cs.sjtu 2011.9程序设计 - 64v在创建一个对象时,可以用一个同类的对象对在创建一个对象时,可以用一个同类的对象对其初始化。这是需要调用一个特殊的构造函数其初始化。这是需要调用一个特殊的构造函数,称为拷贝构造函数。,称为拷贝构造函数。v拷贝构造函数以一个同类对象引用作为参数,拷贝构造函数以一个同类对象引用作为参数,它的原型为:它的原型为: 类名(类名(const &););v用户可以根据自己的需要定义拷贝构造函数用户可以根据自己的需要定义拷贝构造函数程序设计 cs.sjtu 2011.9程序设计 - 65v如果用户没有定义拷贝构造函数,系统如果用户没有定义拷贝构造函数,系统会定

50、义一个缺省的拷贝构造函数。该函会定义一个缺省的拷贝构造函数。该函数将已存在的对象原式原样地复制给新数将已存在的对象原式原样地复制给新成员成员程序设计 cs.sjtu 2011.9程序设计 - 66Classname(const classname &ob)/.例:例:Class point int x, y; public: point(int a, int b) x = a; y = b; point(const point &p) x = 2 * p.x; y = 2 * p.y;程序设计 cs.sjtu 2011.9程序设计 - 67v一般情况下,默认的拷贝构造函数足以满足要求。一般情况

51、下,默认的拷贝构造函数足以满足要求。v但某些情况下可能需要设计自己的拷贝构造函数。但某些情况下可能需要设计自己的拷贝构造函数。v例如,我们希望对例如,我们希望对DoubleArray类增加一个功能,能够定类增加一个功能,能够定义一个和另一个数组完全一样的数组。但默认的拷贝构义一个和另一个数组完全一样的数组。但默认的拷贝构造函数却不能胜任。如果正在构造的对象为造函数却不能胜任。如果正在构造的对象为arr1,作为,作为参数的对象是参数的对象是arr2,调用默认的拷贝构造函数相当于执,调用默认的拷贝构造函数相当于执行下列操作:行下列操作: arr1.low = arr2.low; arr1.high

52、 = arr2.high; arr1.storage = arr2.storage; 前两个操作没有问题,第三个操作中,前两个操作没有问题,第三个操作中,storage是一个指是一个指针,第三个操作意味着使针,第三个操作意味着使arr1的的storage指针和指针和arr2的的storage指针指向同一块空间。指针指向同一块空间。 程序设计 cs.sjtu 2011.9程序设计 - 68v一个对象的修改将会影响另一个对象一个对象的修改将会影响另一个对象v如果两个对象的作用域不同,当一个对如果两个对象的作用域不同,当一个对象析构时,另一个对象也将丧失它的空象析构时,另一个对象也将丧失它的空间间程

53、序设计 cs.sjtu 2011.9程序设计 - 69DoubleArray(const DoubleArray &arr) low = arr.low; high = arr.high; storage = new double high low + 1; for (int i = 0; i high low + 1; +i) storagei = arr.storagei; 程序设计 cs.sjtu 2011.9程序设计 - 70v对象定义时对象定义时 v函数调用时,把对象作为参数传给值函数调用时,把对象作为参数传给值传递的形式参数传递的形式参数v把对象作为返回值时把对象作为返回值时 程序

54、设计 cs.sjtu 2011.9程序设计 - 71v将初始值放在圆括号中,直接调用与实参类将初始值放在圆括号中,直接调用与实参类型相匹配的构造函数。如型相匹配的构造函数。如 DoubleArray array2(array1);v用用“=”符号符号 DoubleArray array = array1; 程序设计 cs.sjtu 2011.9程序设计 - 72class point int x, y; public: point(int a, int b)x=a; y=b; point(const point &p) x=2*p.x; y=2*p.y; void print() coutx

55、yendl;void main()point p1(10, 20), p2(p1), p3 = p1, p4(1, 2); p1.print(); p2.print(); p3.print(); p4.print(); p4 = p1; p4.print(); 10 2020 4020 401210 20程序设计 cs.sjtu 2011.9程序设计 - 73v如有函数:如有函数:void f(DoubleArray array);v函数调用函数调用 f(arr); 将创建一个形式参数对象将创建一个形式参数对象array,并调用,并调用拷贝构造函数用对象拷贝构造函数用对象arr初始化初始化ar

56、rayv注意:如果是引用传递就没有这个构造过注意:如果是引用传递就没有这个构造过程了程了程序设计 cs.sjtu 2011.9程序设计 - 74v如有函数如有函数 DoubleArray f() DoubleArray a; return a; v当执行到当执行到return语句时,会创建一个语句时,会创建一个DoubleArray类的临时对象,并调用拷贝构造函数用对象类的临时对象,并调用拷贝构造函数用对象a初始初始化该临时对象,并将此临时对象的值作为返回值化该临时对象,并将此临时对象的值作为返回值。 程序设计 cs.sjtu 2011.9程序设计 - 75v与普通的内置类型的变量完全相同与普

57、通的内置类型的变量完全相同Time gTime;int main() Time lTime1;static Time sTime;Time lTime2;创建顺序:遇到变量定义时调用构造函数1、gTime构造函数 2、lTime1构造函数 3、sTime构造函数 4、lTime2构造函数程序设计 cs.sjtu 2011.9程序设计 - 76Time gTime;int main()Time lTime1;static Time sTime;Time lTime2;消失顺序:1、局部变量先消失,然后是静态局部变量, 最后是全局变量;2、后创建的先消失;1、lTime2析造函数 2、lTime1

58、析造函数3、sTime析造函数 4、gTime2析造函数程序设计 cs.sjtu 2011.9程序设计 - 77class CreateAndDestroy public: CreateAndDestroy( int, string ); CreateAndDestroy(); private: int objectID; ; 程序设计 cs.sjtu 2011.9程序设计 - 78CreateAndDestroy:CreateAndDestroy( int ID) objectID = ID; cout Object objectID constructor runs endl;Create

59、AndDestroy:CreateAndDestroy() cout Object objectID destructor runs endl; 程序设计 cs.sjtu 2011.9程序设计 - 79CreateAndDestroy first( 1); int main() cout nMAIN FUNCTION: EXECUTION BEGINS endl; CreateAndDestroy second( 2); static CreateAndDestroy third( 3,); create(); cout nMAIN FUNCTION: EXECUTION RESUMES en

60、dl; CreateAndDestroy fourth( 4); cout nMAIN FUNCTION: EXECUTION ENDS endl; return 0;程序设计 cs.sjtu 2011.9程序设计 - 80void create( void ) cout nCREATE FUNCTION: EXECUTION BEGINS endl; CreateAndDestroy fifth( 5); static CreateAndDestroy sixth( 6); CreateAndDestroy seventh( 7); cout nCREATE FUNCTION: EXECUT

61、ION ENDS endl;程序设计 cs.sjtu 2011.9程序设计 - 81void create( void ); int main() create(); create(); return 0;测试静态的局部变量程序设计 cs.sjtu 2011.9程序设计 - 82v从面向过程到面向对象从面向过程到面向对象 v类的定义类的定义 v对象的使用对象的使用v对象的构造与析构对象的构造与析构 v常量对象与常量对象与const成员函数成员函数 v常量数据成员常量数据成员 v静态数据成员与静态成员函数静态数据成员与静态成员函数 v友元友元 程序设计 cs.sjtu 2011.9程序设计 -

62、83vconst对象的定义对象的定义 const MyClass obj(参数表);(参数表);vconst对象不能被赋值,只能初始化,而对象不能被赋值,只能初始化,而且一定要初始化,否则无法设置它的值且一定要初始化,否则无法设置它的值。程序设计 cs.sjtu 2011.9程序设计 - 84v数据成员一般都由成员函数修改。当定数据成员一般都由成员函数修改。当定义了一个常量对象后,如何使用这个对义了一个常量对象后,如何使用这个对象?象?vC+规定:对规定:对const对象只能调用对象只能调用const成成员函数员函数程序设计 cs.sjtu 2011.9程序设计 - 85v任何不修改数据成员的

63、函数都应该声明为任何不修改数据成员的函数都应该声明为const类类型。如果在编写型。如果在编写const成员函数时,不慎修改了数成员函数时,不慎修改了数据成员,或者调用了其他非据成员,或者调用了其他非const成员函数,编译成员函数,编译器将指出错误,这无疑会提高程序的健壮性。器将指出错误,这无疑会提高程序的健壮性。 class A int x; public: A(int i) x=i; int getx() const return x; ;程序设计 cs.sjtu 2011.9程序设计 - 86class A int x; public: A(int i) x=i; int getx()

64、 const; ; int A:getx() const return x; 必须加必须加程序设计 cs.sjtu 2011.9程序设计 - 87class A int x;public:A(int i) x=i;int getx() const x =7; /错误,修改了数据成员错误,修改了数据成员x return x;程序设计 cs.sjtu 2011.9程序设计 - 88v从面向过程到面向对象从面向过程到面向对象 v类的定义类的定义 v对象的使用对象的使用v对象的构造与析构对象的构造与析构 v常量对象与常量对象与const成员函数成员函数 v常量数据成员常量数据成员 v静态数据成员与静态

65、成员函数静态数据成员与静态成员函数 v友元友元 程序设计 cs.sjtu 2011.9程序设计 - 89vconst数据成员只在某个对象生存期内是常量,而数据成员只在某个对象生存期内是常量,而对于整个类而言却是可变的。同一类的不同的对象对于整个类而言却是可变的。同一类的不同的对象其其const数据成员的值可以不同。数据成员的值可以不同。v常量成员的声明常量成员的声明 在该成员声明前加上在该成员声明前加上const。如。如 class abc const int x; ;程序设计 cs.sjtu 2011.9程序设计 - 90v不能在类声明中初始化不能在类声明中初始化const数据成员。数据成员

66、。class A/错误,企图在类声明中初始化错误,企图在类声明中初始化const数据成员数据成员const int SIZE = 200;int arraySIZE; /错误,未知的错误,未知的SIZE;程序设计 cs.sjtu 2011.9程序设计 - 91vconst数据成员的初始化只能在类构造函数的初数据成员的初始化只能在类构造函数的初始化表中进行,不能在构造函数中对他赋值。始化表中进行,不能在构造函数中对他赋值。v例:例:class AA(int size);/构造函数构造函数const int SIZE;A:A(int size) : SIZE(size)/构造函数的初始化表构造函数的初始化表A a(100);/对象对象a的的SIZE的值为的值为100A b(200);/对象对象b的的SIZE的值为的值为200程序设计 cs.sjtu 2011.9程序设计 - 92v从面向过程到面向对象从面向过程到面向对象 v类的定义类的定义 v对象的使用对象的使用v对象的构造与析构对象的构造与析构 v常量对象与常量对象与const成员函数成员函数 v常量数据成员常量数据成员 v静态数据成员

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

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!