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

下载本文档

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

文档简介

1、1第三章第三章类和对象类和对象23.1 类与对象的基本概念类与对象的基本概念3.1.1 结构与类结构与类1. 结构的扩充结构的扩充 C+中对中对C语言的结构类型进行了扩充,它还可以含有函数。如:语言的结构类型进行了扩充,它还可以含有函数。如:struct complex double real; /复数的实部复数的实部 double imag; /复数的虚部复数的虚部 void init (double r, double I) /给给real和和imag赋初值赋初值 real=r; imag=i; double realcomplex() /取复数的实部取复数的实部值值 return rea

2、l; double imagcomplex() /取复数的虚部值取复数的虚部值 return imag; double abscomplex() /求复数的绝对求复数的绝对值值 double t; t=real*real+imag*imag; return agrt(t); ;结构类型中的数据和函数,分别称为数据成员和函数成员;结构类型中的数据和函数,分别称为数据成员和函数成员。3*例例 3.1#include #include struct complex double real; /复数的实部复数的实部 double imag; /复数的虚部复数的虚部 void init (double

3、r, double I) /给给real和和imag赋初值赋初值 real=r; imag=i; double realcomplex() /取复数的实部值取复数的实部值 return real; double imagcomplex() /取复数的虚部值取复数的虚部值 return imag; double abscomplex() /求复数的绝对值求复数的绝对值 double t; t=real*real+imag*imag; return sqrt(t); A;void main() A.init(1.1,2.2);cout“复数复数A的实部的实部=“A.realcomplex()end

4、l;cout“复数复数A的实部的实部=“A.imagcomplex()endl;cout“复数复数A的绝对值的绝对值=“A.abscomplex()endl;42. 类的定义类的定义(声明声明)C+中说明类的一般形式为中说明类的一般形式为 clsaa 类名类名 private: (可缺省可缺省) 私有数据成员和函数成员私有数据成员和函数成员 protected: 保护段保护段 public: 公有数据成员和函数成员公有数据成员和函数成员 ;class complex private: double real, imag; public: void init (double r, double

5、i) real=r; imag=i; double realcomplex() return real; double imagcomplex() return imag; double abscomplex() double t; t=real*real+imag*imag; return sqrt(t); ;类类 class 和结构和结构 sturct 的主要区别是:的主要区别是:在缺省在缺省 private 时,时,在类中,成员是私有的在类中,成员是私有的在结构中,成员是公有的在结构中,成员是公有的5例例 3.2#include #include class complex privat

6、e: double real, imag; public: void init (double r, double i) real=r; imag=i; double realcomplex() return real; double imagcomplex() return imag; double abscomplex() double t; t=real*real+imag*imag; return sqrt(t); ;void main( ) complex A; A.init(1.1,2.2); cout“复数复数A的实部的实部=“A.realcomplex()endl; cout“

7、复数复数A的实部的实部=“A.imagcomplex()endl; cout“复数复数A的绝对值的绝对值=“A.abscomplex()endl;63.1.2 成员函数的定义成员函数的定义第一种方式是在类定义中只给出成员函数的原型(或者说声明),第一种方式是在类定义中只给出成员函数的原型(或者说声明),而成员函数在类的外部定义。在外部定义的一般形式是:而成员函数在类的外部定义。在外部定义的一般形式是:返回类型返回类型 类名类名:函数名函数名(参数表参数表) / 函数体函数体class point / 定义类定义类 point private: int x, y; / 数据成员,二个整数作为数据

8、成员,二个整数作为 x,y 坐标坐标 public: void setpoint(int, int); / 函数成员,名为函数成员,名为setpoint ,有二个,有二个整数形参,用于设置坐标值,具体如何在外部再定义,这叫函数整数形参,用于设置坐标值,具体如何在外部再定义,这叫函数的原型(或者说声明)的原型(或者说声明) int getx(); /取取 x 坐标值的成员函数坐标值的成员函数getx()的函数原型的函数原型 int gety(); /取取 y 坐标值的成员函数坐标值的成员函数gety()的函数原型的函数原型; /类定义结束类定义结束viod point:setpoint(int

9、a, int b) /成员函数成员函数 setpoint 具体定义具体定义 x=a; y=b; int point: getx() /成员函数成员函数 getx 具体定义具体定义 return x; int point: grty() /成员函数成员函数 gety 具体定义具体定义 return y; 7说明说明(1)在所定义的成员函数名之前应缀上类名,在类名和函数名之)在所定义的成员函数名之前应缀上类名,在类名和函数名之间应加上分隔符间应加上分隔符“:”,例如上面例子中的,例如上面例子中的“point:”。(2)在定义成员函数时,对函数所带的参数,不但要说明它的类)在定义成员函数时,对函数所

10、带的参数,不但要说明它的类型,还要指出其参数名。型,还要指出其参数名。(3)在定义成员函数时,其返回类型一定要与函数原型中声明的)在定义成员函数时,其返回类型一定要与函数原型中声明的返回类型匹配。返回类型匹配。 第二种方式是将成员函数定义在类的内部,即定义为内置函数。第二种方式是将成员函数定义在类的内部,即定义为内置函数。又可用两种:又可用两种:(1) 隐式定义隐式定义 即函数的原型和定义都在类的内部完成即函数的原型和定义都在类的内部完成class point / 定义类定义类 point private: int x, y; / 数据成员,二个整数作为数据成员,二个整数作为 x,y 坐标坐标

11、 public: void setpoint(int a, int b) / 函数成员函数成员 x=a; y=b; int getx() return x; int gety() return y; ; /类定义结束类定义结束8(2) 显式定义显式定义即在类定义中仍只给出成员函数的原型(或者说声明),而成员函即在类定义中仍只给出成员函数的原型(或者说声明),而成员函数在类的外部定义。但函数定义前冠以关键字数在类的外部定义。但函数定义前冠以关键字 “inline”,以此显,以此显式地说明这是一内置函数。式地说明这是一内置函数。class point / 定义类定义类 point private:

12、 int x, y; / 数据成员,二个整数作为数据成员,二个整数作为 x,y 坐标坐标 public: void setpoint(int, int); / 函数成员函数成员setpoint ,有二个整数形参,有二个整数形参 int getx(); /取取 x 坐标值的成员函数坐标值的成员函数getx()的函数原型的函数原型 int gety(); /取取 y 坐标值的成员函数坐标值的成员函数gety()的函数原型的函数原型; /类定义结束类定义结束inline viod point:setpoint(int a, int b) /内置成员函数具体定义内置成员函数具体定义 x=a; y=b;

13、 inline int point: getx() /内置成员函数内置成员函数 getx 具体定义具体定义 return x; inline int point: grty() /内置成员函数内置成员函数 gety 具体定义具体定义 return y; 把成员函数设置成内置,可提高执行的效率,但函数体较长的成员把成员函数设置成内置,可提高执行的效率,但函数体较长的成员函数都不设置成内置。函数都不设置成内置。93.1.3 对象的定义及引用对象的定义及引用1. 类与对象的关系类与对象的关系 可以用整型可以用整型 int 和整型变量和整型变量 i 之间的来类比。之间的来类比。int i ;2. 对象

14、的定义对象的定义(1) 在声明类的同时,直接定义对象在声明类的同时,直接定义对象 op1, op2class point / 定义类定义类 point private: int x, y; / 数据成员,二个整数作为数据成员,二个整数作为 x,y 坐标坐标 public: void setpoint(int, int); int getx(); int gety(); op1, op2; (2) 声明了类之后,在使用时再定义对象,定义的格式与一般变声明了类之后,在使用时再定义对象,定义的格式与一般变量的定义格式相同:量的定义格式相同: point op1, op2;说明:(说明:(1) 声明了

15、一个类便声明了一种类型,它并不接收和存储声明了一个类便声明了一种类型,它并不接收和存储具体的值,只有定义了对象后,系统才为对象并且只为对象分配具体的值,只有定义了对象后,系统才为对象并且只为对象分配存储空间。存储空间。 (2) 在声明类的同时定义的对象是一种全局对象,在它的在声明类的同时定义的对象是一种全局对象,在它的生存期内任何函数都可以使用它。生存期内任何函数都可以使用它。103对象的引用对象的引用 对象的引用是指对象的成员的引用,不论是数据成员,还是成员对象的引用是指对象的成员的引用,不论是数据成员,还是成员函数,只要是公有的,就可以被外部函数直接引用,引用格式是:函数,只要是公有的,就

16、可以被外部函数直接引用,引用格式是: 对象名对象名. 数据成员名数据成员名 或或 对象名对象名. 成员函数名(实参表)成员函数名(实参表)例例 3.3#include class point private: int x, y; public: void setpoint(int a, int b) x=a; y=b; int getx() return x; int gety() return y; ;void main() point op1, op2; int i, j; op1.setpoint(1,2);/调用调用op1的的setpoint(),初始化对象,初始化对象op1 op2.

17、setpoint(3,4);/调用调用op2的的setpoint(),初始化对象,初始化对象op2 i=op1.getx(); /调用调用op1的的getx(),取,取op1的的x值值 j=op1.gety(); /调用调用op1的的gety(),取,取op1的的y值值 cout“op1 i=”i“ op1 j=”jendl; i=op2.getx(); /调用调用op2的的getx(),取,取op2的的x值值 j=op2.gety(); /调用调用op2的的gety(),取,取op2的的y值值 cout“op2 i=”i“ op2 j=”jendl;11说明说明(1) 本例中本例中op1.s

18、etpoint(1,2)实际上是实际上是op1.point:setpoint(1,2)的一的一种缩写形式。种缩写形式。(2) 外部函数不能引用对象的私有成员。外部函数不能引用对象的私有成员。void main() point op; int i, j; op.setpoint(1,2); i=op.x; /错误,不能直接引用对象的私有成员错误,不能直接引用对象的私有成员 j=op.y; /错误,不能直接引用对象的私有成员错误,不能直接引用对象的私有成员 cout“op i=”i“ op j=”j”操作符。操作符。 point *op; op-setpoint(5,6); i=op-getx()

19、; j=op-gety();124. 对象赋值语句对象赋值语句 同类型的对象之间也可以进行赋值,当一个对象赋值给另一个对同类型的对象之间也可以进行赋值,当一个对象赋值给另一个对象时,所有的数据成员都会逐位拷贝。象时,所有的数据成员都会逐位拷贝。例例 3.4#include class myclass int a,b; public: void set(int i, int j) a=i; b=j; void show() couta“ “bendl; ;void main( ) myclass o1, o2; o1.set(20,5); o2=o1; /将对象将对象o1的值赋给将对象的值赋给将

20、对象o2 o1.show(); o2.show();(1)对象赋值时,两对象赋值时,两个对象的类型必须个对象的类型必须相同。相同。(2)对象赋值时,仅对象赋值时,仅仅使对象中的数据仅使对象中的数据相同,两个对象仍相同,两个对象仍是独立的。是独立的。(3)两个对象赋值时,两个对象赋值时,多数情况是成功的,多数情况是成功的,但当类中有指针成但当类中有指针成员时,可能会发生员时,可能会发生错误。错误。133.1.4 类的作用域类的作用域 所谓类的作用域就是指在类的声明中的一对花括号所形成的作用域。所谓类的作用域就是指在类的声明中的一对花括号所形成的作用域。 一个类的成员函数可以不受限制地引用该类的数

21、据成员,而在该类一个类的成员函数可以不受限制地引用该类的数据成员,而在该类作用域之外,对该类的数据成员和成员函数的引用则要受到一定作用域之外,对该类的数据成员和成员函数的引用则要受到一定的限制,有时甚至是不允许的。这体现了类的封装性。的限制,有时甚至是不允许的。这体现了类的封装性。例例 3.5#include class abc public: int i; void set(int); void disp() cout“i=“iendl; /可以直接引用类中的数据成员可以直接引用类中的数据成员i;void main() abc ob; ob.set(2); /通过成员函数给数据成员通过成员函

22、数给数据成员i赋初值赋初值2 ob.disp(); i=1; /非法,不能直接引用类中的数据成员非法,不能直接引用类中的数据成员i,可,可 / 改为改为ob.i=1; ob.disp();void abc:set(int si) i=si; /成员函数可以直接引用类中的数据成员成员函数可以直接引用类中的数据成员iint fun() return i; /非法,不能直接引用类中的数据成员非法,不能直接引用类中的数据成员i14*3.1.5 定义类定义类1. 说明类说明类 C+中说明类的一般形式为中说明类的一般形式为 clsaa 类名类名 private: (可缺省可缺省) 私有数据和函数私有数据和

23、函数 (私有成员私有成员) protected: 保护段保护段 public: 公有数据和函数公有数据和函数 (公有成员公有成员) ;2. 类标识符类标识符3. 类体类体(成员函数体成员函数体)成员函数可以在定义类时同时说明和定义成员函数可以在定义类时同时说明和定义 class Location private: int X, Y; public: void init(int initX, int initY) X=initX; Y=initY; ; int GetX() return X; int GetY() return Y; 也可先说明另外单独定义。也可先说明另外单独定义。 class

24、 Location private: int X, Y; public: void init(int initX, int initY) int GetX(); int GetY(); ; void Location:init(int initX, int initY) X=initX; Y=initY; int Location:GetX() return X; int Location:GetY() return Y; 返回类型返回类型 类名类名:成员函数名成员函数名(参数说明参数说明) 类体类体 16*3.1.6使用类使用类1. 对象说明对象说明(定义对象定义对象)可以使用类在程序中定义

25、变量,这种变量即为对象可以使用类在程序中定义变量,这种变量即为对象 Location A1,A2; 【例【例2.7】 Location 类的一个完整程序,可上机。类的一个完整程序,可上机。 #include class Location private: int X, Y; public: void init(int initX, int initY) int GetX(); int GetY(); ; void Location:init(int initX, int initY) X=initX; Y=initY; int Location:GetX() return X; int Loc

26、ation:GetY() return Y; void main( ) Location A1,A2; A1.init(5,3); A2.init(6,8); cout A1.GetX() A1.GetY()endl; cout A2.GetX() A2.GetY()endl;/ 或或 Location *pA1, *pA2; pA1=&A1; pA2=&A2; cout GetX() GetY()endl; cout GetX() GetY()endl;172. 封装性封装性用用 class 定义类,实现了封装,定义类,实现了封装,C+中还可用中还可用 struct、union等等3. 类的

27、存取控制类的存取控制 类的使用者有如下三种:类的使用者有如下三种: 类本身类本身 一般用户一般用户 派生类派生类 每一种使用者对类的数据有不同的权限每一种使用者对类的数据有不同的权限 private public protected4. 类的私有成员类的私有成员 private 只有类本身只有类本身(或类的友元或类的友元)可以存取私有成员。可以存取私有成员。 要使类在程序中被使用,所以类必须至少有一个非私有成员。要使类在程序中被使用,所以类必须至少有一个非私有成员。5. 类的公有成员类的公有成员 pubilc 在在public部分定义的内容允许被其它对象无限制地存取。另外部分定义的内容允许被其

28、它对象无限制地存取。另外C+可以有限制地使用可以有限制地使用 public成员存取成员存取private成员。成员。 18【例】使用类,设计模似数字式时钟的程序【例】使用类,设计模似数字式时钟的程序一般较大的程序用模块化的方法,分成三个文件一般较大的程序用模块化的方法,分成三个文件 *.h 文件,用来描述类。文件,用来描述类。 *.cpp 文件,用来实现类,其中是成员函数的定义。文件,用来实现类,其中是成员函数的定义。 *.cpp 文件,用来写文件,用来写 main( ) 函数。函数。 /clock.h class Clock private: int hour,minute,second;

29、public: void init(); void update(); void display(); ; 19/clock.cpp #include #include clock.h void Clock:init() hour=minute=secind=0; void Clock:update() second+; if(second=60) second=0; minute+; if(minute=60) minute=0; hour+; if(hour=24) hour=0; void Clock:display() cout“hour“:”minute“:”secondendl;

30、20/mymain.cpp #inclode clock.cpp void main( ) Clock clockA, clockB; coutCLOCK A:endl; clockA.init(); for(int i=0;i10;i+) clockA.update(); clockA.display(); coutCLOCK B:endl; clockB.init(); for(i=0;i20;i+) clockB.update(); clockB.display(); 21 (1) 函数函数main()不能访问对象不能访问对象clockA内部私有数据和函数,内部私有数据和函数,Clock

31、类类的修改不必改的修改不必改main()中程序。中程序。(2) Clock类受封装保护。类受封装保护。(3) 类只需定义一次,就可通过实例化建立多个对象。类只需定义一次,就可通过实例化建立多个对象。(4) 三个清楚的模块。三个清楚的模块。6. 类的保护成员类的保护成员 protected 当定义类是为了以后作其它类的基类时,可以定义类的保护成员当定义类是为了以后作其它类的基类时,可以定义类的保护成员。22*3.1.7 内联成员函数内联成员函数 在类定义内只有成员函数的声明,而在外面定义完整的成员函数,在类定义内只有成员函数的声明,而在外面定义完整的成员函数,并且前面加并且前面加 inline

32、,这样的成员函数叫内联成员函数。编译器会,这样的成员函数叫内联成员函数。编译器会自动用函数体去替换函数声明,其目的是提高程序的效率。自动用函数体去替换函数声明,其目的是提高程序的效率。 class Location private: int X,Y; public: void init(int initX, int initY); /成员函数的声明成员函数的声明 int GetX(); /成员函数的声明成员函数的声明 int Gety(); /成员函数的声明成员函数的声明 ; inline void Location:init(int initX, int initY) X = initX;

33、Y = initY; inline int Location:GetX() return X; inline int Location:GetY() return Y; 考虑到程序的运行效率,简单的成员函数一般与类考虑到程序的运行效率,简单的成员函数一般与类定义同时定义或定义同时定义或 被实现为内联函数。被实现为内联函数。23*3.1.8成员函数的重载及其缺省参数值成员函数的重载及其缺省参数值 在类说明中可以定义同名的成员函数,称为重载。这时这两个函数在类说明中可以定义同名的成员函数,称为重载。这时这两个函数应该有不同的形参情况及函数体,完成不同的程序功能。应该有不同的形参情况及函数体,完成不

34、同的程序功能。在类说明中定义成员函数时可以对形参给以缺省值,称为带缺省参在类说明中定义成员函数时可以对形参给以缺省值,称为带缺省参数值的成员函数。数值的成员函数。#include class Location private: int X,Y; public: void init(int=0 , int=0); /带缺省参数值的成员函数带缺省参数值的成员函数 void valueX(int); /这两个函数同名,都叫这两个函数同名,都叫valueX int valueX( ); /但有不同的形参和返回值但有不同的形参和返回值 void valueY(int); int valueY( ); ;

35、24void Location:init(int initX, int initY) X = initX; Y = initY; void Location:valueX(int val) X=val; int Location:valueX( ) return X; void Location:valueY(int val) Y=val; int Location:valueY( ) return Y; void main( ) Location LA, LB; LA.init( ); /对象对象 LA 的数据成员的数据成员 X 和和 Y 被置为被置为 0 LA.valueX(5); /将成

36、员将成员 X 重置为重置为 5 coutLA.valueX( )endlLA.valueY( )endl; LB.init(6,2); /对象对象 LB 的的 数据成员数据成员 X 和和 Y 被置为被置为 6 和和 2 LB.valueY(4); /将成员将成员 Y 重置为重置为 4 coutLB.valueX( )endlLB.valueY( ) LA这里举一个例子说明这里举一个例子说明 this 指针的用处,假定类中增加一个成员函数指针的用处,假定类中增加一个成员函数取名为取名为赋值赋值 assign() void Location:assign(Location& p) if (this

37、 = &p) ; else X=p.X; Y=p.Y 当有二个对象当有二个对象 Location LA, LB; 若若 LA.assign(LA); 则则this=&p即即LA成立,执行空语句,表示同一成立,执行空语句,表示同一个对象之间相互赋值没有意义,若个对象之间相互赋值没有意义,若 LA.assign(LB); 则则 this(LA) 不不等于等于 &p(LB),则,则 LA.X(或或this-X)=p.X; LA.Y=p.Y; 这里就可以这里就可以用来判别接受引用的对象是自己还是另外的对象。用来判别接受引用的对象是自己还是另外的对象。27*3.1.11类的其它基础知识类的其它基础知识

38、类的作用域类的作用域1. 在类说明在类说明 中的标识符只在类中可见。类中各数据成员的生存期中的标识符只在类中可见。类中各数据成员的生存期由类对象的生存期决定,当对象存在时,它们存在;对象消失时,由类对象的生存期决定,当对象存在时,它们存在;对象消失时,它们也消失。它们也消失。 class MyClass private: int number; public: void set(int i); int j=number; /出错,出错,number 在此不可见在此不可见 int number; void MyClass:set(int i) number = i; /此此 number 为为

39、MyClass 中的中的number 282. 一个类的说明也分为声明和定义性说明。一个类的说明也分为声明和定义性说明。 class Location; /声明声明 声明的类名不能用来建立对象,只能用来建立指针或引用。声明的类名不能用来建立对象,只能用来建立指针或引用。 Location LA; /错错 Location *Pa; /对对 class Location . . /定义定义 Location LA; /对对 Location *Pa; /对对空类空类 class 名名 ; 中没有数据成员和函数成员称为空类,空类可以建立对象。中没有数据成员和函数成员称为空类,空类可以建立对象。类对

40、象的存储方式类对象的存储方式 定义类对象时也可加定义类对象时也可加auto、register、extern、static等存储方式。等存储方式。类嵌套类嵌套 类定义中的成员可以是类,称为类嵌套。类定义中的成员可以是类,称为类嵌套。类的实例化类的实例化 当用一个类定义对象时,当用一个类定义对象时,+才进行存储分配。这种对象建立的才进行存储分配。这种对象建立的过程称为实例化。过程称为实例化。 293.2 构造函数与析构函数构造函数与析构函数3.2.1 构造函数构造函数当类定义时把数据成员定义成公有成员时,可用传统的方法给它赋当类定义时把数据成员定义成公有成员时,可用传统的方法给它赋初值。初值。C语

41、言语言 传统的方法传统的方法 main() struct student int sno; char *sname; float score; ; struct student s1=9801,张三张三,89.5;class Init public: int i; char *name; float num2; ; Init C = 34,program,56.89,1.2; 对于更一般的类型,我们用构造函数的方法。对于更一般的类型,我们用构造函数的方法。30构造函数构造函数构造函数是特殊成员函数,具有一些特殊的性质:构造函数是特殊成员函数,具有一些特殊的性质:(1) 构造函数的名字必须与类名

42、相同。构造函数的名字必须与类名相同。(2) 构造函数可以有任意类型的参数,但不能具有返回类型。构造函数可以有任意类型的参数,但不能具有返回类型。(3) 定义对象时,编译系统会自动地调用构造函数。定义对象时,编译系统会自动地调用构造函数。class complex private: double real, imag; public: complex(double r, double i) real=r; imag=i; double abscomplex() double t; t=real*real+imag*imag; return sqrt(t); 构造函数不能像其它成员函数那样被显式地

43、调用,它是在定义对构造函数不能像其它成员函数那样被显式地调用,它是在定义对象的同时调用的,其一般格式为:象的同时调用的,其一般格式为: 类名类名 对象名(实参表)对象名(实参表)31构造函数的调用构造函数的调用例例 3.6#include #include class complex private: double real, imag; public: complex(double r, double i) real=r; imag=i; double abscomplex() double t; t=real*real+imag*imag; return sqrt(t); ;void ma

44、in() complex A(1.1,2.2); /定义对象定义对象 A时自动调用构造函数时自动调用构造函数complex cout“复数复数A的绝对值的绝对值=“A.abscomplex()endl;32说明:说明:(1) 构造函数的名字必须与类名相同,否则编译程序将把它当作构造函数的名字必须与类名相同,否则编译程序将把它当作一般的成员函数来处理。一般的成员函数来处理。(2) 构造函数没有返回值,在声明和定义构造函数时,是不能说构造函数没有返回值,在声明和定义构造函数时,是不能说明它的类型的的,甚至说明为明它的类型的的,甚至说明为void类型也不行。类型也不行。(3) 在实际应用中,通常需要

45、给每个类定义构造函数。如果没有在实际应用中,通常需要给每个类定义构造函数。如果没有给类定义构造函数,则编译系统自动地生成一个缺省的构造函数。给类定义构造函数,则编译系统自动地生成一个缺省的构造函数。 complex:complex() (4) 构造函数可以是不带参数的。构造函数可以是不带参数的。(5) 构造函数也可采用构造初始化表对数据成员进行初始化,这构造函数也可采用构造初始化表对数据成员进行初始化,这是某些程序员喜欢使用的方法。是某些程序员喜欢使用的方法。 class A int i, j; float f; public: A(int I, int J, float F):i(I),j(

46、J),f(F) ;(6) 对没有定义构造函数的类,其公有数据成员可以用传统的方对没有定义构造函数的类,其公有数据成员可以用传统的方法初始值表进行初始化。法初始值表进行初始化。33定义构造函数定义构造函数 在类定义时可以定义一种与类名同名的成员函数,我们称之为构在类定义时可以定义一种与类名同名的成员函数,我们称之为构造函数。它有如下的要点造函数。它有如下的要点 要点要点1. 构造函数与类名同名,且要有函数体,可以内置或外置或构造函数与类名同名,且要有函数体,可以内置或外置或内联,没有返类型(内联,没有返类型(void也不能写)。也不能写)。 要点要点2. 构造函数不能象其他成员函数那样被外界调用

47、,它在程序构造函数不能象其他成员函数那样被外界调用,它在程序定义一个新对象,定义一个新对象, 程序自动调用构造函数来初始化这个对象。程序自动调用构造函数来初始化这个对象。 要点要点3. 构造函数可不带形式参数也可带形式参数,这样可根据不构造函数可不带形式参数也可带形式参数,这样可根据不同的要求对对象不同的初始化。同的要求对对象不同的初始化。【例例】 / test.h class test private: int num; float fl; public : test(); test(int n, float f); int getint() return num; float getflo

48、at() return fl; ;34test:test() cout“这是缺省参数的构造函数进行初始化这是缺省参数的构造函数进行初始化endl; num=0; fl=0.0; test:test(int n, float f) cout“这是带参数的构造函数进行初始化这是带参数的构造函数进行初始化 nfendl; num=n; fl=f; 下面用类定义对象时,会自动调用以上构造函数下面用类定义对象时,会自动调用以上构造函数#include #include test.h void main() test x; test y(10, 21.5); 执行这个程序,产生如下输出:执行这个程序,产生

49、如下输出: 这是缺省参数的构造函数进行初始化这是缺省参数的构造函数进行初始化 这是带参数的构造函数进行初始化这是带参数的构造函数进行初始化 10 21.535 构造函数和运算符构造函数和运算符new,delete运算符运算符new可动态可动态(生存期可控生存期可控)的建立一个对象,的建立一个对象,new返回这个对象返回这个对象的指针。的指针。 执行运算符执行运算符new时,时,new先分配足够内存,然后自动调用构造函数先分配足够内存,然后自动调用构造函数给这内存赋初值给这内存赋初值,再返回这个内存的地址。,再返回这个内存的地址。 void main() test *prt1=new test;

50、 test *prt2=new test(5, 12.8); delete prt1; delete prt2; 执行这个程序,产生如下输出:执行这个程序,产生如下输出: 这是缺省参数的构造函数进行初始化这是缺省参数的构造函数进行初始化 Initializing default 这是带参数的构造函数进行初始化这是带参数的构造函数进行初始化 5 12.8 Initialzing 用用new建立的对象在不用时可用建立的对象在不用时可用delete删除。删除。363.2.2 缺省参数的构造函数缺省参数的构造函数如果定义对象时给一个默认值,这时可以将其定义成带缺省参数的如果定义对象时给一个默认值,这时

51、可以将其定义成带缺省参数的构造函数。构造函数。class complex private: double real, imag; public: complex(double r=0.0, double i=0.0); /带缺省参数的构造函数带缺省参数的构造函数 double abscomplex();complex:complex(double r, double i) /带参数的构造函数带参数的构造函数 real=r; imag=i; double complex:abscomplex(); double t; t=real*real+imag*imag; return sqrt(t);

52、complex S1; / S1为为 0.0, 0.0 的对象的对象complex S2(1.1); / 只给一个参数只给一个参数complex S3(1.1,2.2); / 给二个参数给二个参数373.2.3 析构函数析构函数析构函数也是特殊成员函数,用于释放对象。析构函数也是特殊成员函数,用于释放对象。(1) 析构函数与构造函数名字相同,但它前面必须加一个波浪号析构函数与构造函数名字相同,但它前面必须加一个波浪号()。)。(2) 析构函数没有参数,也没有返回值,而且不能重载,因此在析构函数没有参数,也没有返回值,而且不能重载,因此在一个类中只能有一个析构函数。一个类中只能有一个析构函数。(

53、3) 当撤消对象时,编译系统会自动地调用析构函数。当撤消对象时,编译系统会自动地调用析构函数。例例 3.8#include #include class complex private: double real, imag; public: complex(double r=0.0, double i=0.0) ; /带缺省参数的构造函数带缺省参数的构造函数 complex(); /声明析构函数声明析构函数 double abscomplex();38接例接例 3.8complex:complex(double r, double i) /带参数的构造函数带参数的构造函数 cout“进入构造函

54、数进入构造函数.”endl; real=r; imag=i; complex:complex() /定义析构函数定义析构函数 cout“进入析构函数进入析构函数.”endl; double complex:abscomplex() double t; t=real*real+imag*imag; return sqrt(t); void main() complex A(1.1,2.2); /定义对象定义对象 A时自动调用构造函数时自动调用构造函数complex cout“复数复数A的绝对值的绝对值=“A.abscomplex()endl; /结束时自动调用析构函数结束时自动调用析构函数如果没

55、有给类定义析构函数,则编译系统自动地生成一个缺省的析如果没有给类定义析构函数,则编译系统自动地生成一个缺省的析构函数:构函数: complex:complex() 39定义析构函数定义析构函数在类定义时可以定义另一种与类名同名前面加在类定义时可以定义另一种与类名同名前面加的成员函数,的成员函数, 我们我们称之为析构函数。称之为析构函数。 它有如下的要点它有如下的要点 要点要点1. 析构函数与类名同名,但它前面必须加波浪号析构函数与类名同名,但它前面必须加波浪号()且要有函数体,可以内置或外置或内联,没有返回类型且要有函数体,可以内置或外置或内联,没有返回类型(void也不能写)。也不能写)。

56、要点要点2. 析构函数不能象其他成员函数那样被外界调用,析构函数不能象其他成员函数那样被外界调用,它在程序结束时,程序自动调用析构函数来析放对象的它在程序结束时,程序自动调用析构函数来析放对象的内存。内存。 要点要点3. 析构函数可不带形式参数,不能重载,因此在一析构函数可不带形式参数,不能重载,因此在一个类中只能有一个析构函数。个类中只能有一个析构函数。40【例例】/ test2.hclass test private: int num; float fl; public : test(); test(int n, float f); int getint() return num; flo

57、at getfloat() return fl; test(); ;test:test() num=0; fl=0.0; test:test(int n, float f) num=n; fl=f; test:test() cout Destructor is active显示一下己调用析构函数我显示一下己调用析构函数我endl; 41下面程序运行结束时,会自动调用下面程序运行结束时,会自动调用以上析构函数。以上析构函数。 #include #include test2.h void main() test x; cout退出退出 main 函数函数endl; 执行这个程序,产生如下输出执行这

58、个程序,产生如下输出: 退出退出 main 函数函数 Destructor is active 显示一下己调用析构函数我显示一下己调用析构函数我 全局对象或静态对象的析构函数在程序运行结束之前调用全局对象或静态对象的析构函数在程序运行结束之前调用42析构函数和对象数组析构函数和对象数组 对象数组的每一个元素调用一次析构函数。对象数组的每一个元素调用一次析构函数。 #include #include test2.h void main() test array3; cout退出退出 main 函数函数endl; 执行这个程序,产生如下输出:执行这个程序,产生如下输出: 退出退出 main 函数函

59、数 Destructor is active 显示一下己调用析构函数我显示一下己调用析构函数我 Destructor is active 显示一下己调用析构函数我显示一下己调用析构函数我 Destructor is active 显示一下己调用析构函数我显示一下己调用析构函数我 43析构函数和运算符析构函数和运算符delete用运算符用运算符delete删除一个动态对象时,它首先调用析构函数,删除一个动态对象时,它首先调用析构函数,然后再释放内存。然后再释放内存。 #include #include test2.h void main() test *prt = new test5; dele

60、te prt; 执行这个程序,产生如下输出:执行这个程序,产生如下输出: Destructor is active 显示一下己调用析构函数我显示一下己调用析构函数我 Destructor is active 显示一下己调用析构函数我显示一下己调用析构函数我 Destructor is active 显示一下己调用析构函数我显示一下己调用析构函数我 Destructor is active 显示一下己调用析构函数我显示一下己调用析构函数我 Destructor is active 显示一下己调用析构函数我显示一下己调用析构函数我 44缺省析构函数缺省析构函数 当类定义时没有定义任何析构函数,则自

温馨提示

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

评论

0/150

提交评论