面向对象的程序设计chapter3_第1页
面向对象的程序设计chapter3_第2页
面向对象的程序设计chapter3_第3页
面向对象的程序设计chapter3_第4页
面向对象的程序设计chapter3_第5页
已阅读5页,还剩84页未读 继续免费阅读

下载本文档

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

文档简介

1、1第第3 3章章 类和对象类和对象2主要内容主要内容1.1. 类类2.2. 对象对象3.3. 对象成员变量对象成员变量4.4. 内部类内部类5.5. staticstatic成员成员6.6. 自引用对象指针自引用对象指针thisthis7.7. 设计举例设计举例gogo33.1 3.1 类类1.1.类的定义类的定义类是对具有相同属性和相同行为的客观世界的一组类是对具有相同属性和相同行为的客观世界的一组相似对象的抽象。相似对象的抽象。类的定义形式为:类的定义形式为: classclass 类名类名 private:private: protected:protected: public:publ

2、ic: ; ;类的作用域类的作用域43.1 3.1 类类1.1. 类的定义类的定义 访问权限关键字访问权限关键字private-private-说明的成员只能在该类中使用,说明的成员只能在该类中使用,即在类的外面不能直接访问即在类的外面不能直接访问 private private 成员,成员,类的默认访问权限为类的默认访问权限为privateprivate。public-public-说明的成员不但可以在该类中使说明的成员不但可以在该类中使用,而且其他的函数或类可以直接访问用,而且其他的函数或类可以直接访问 pubpubliclic成员。成员。protected-protected-说明的成员

3、可以在该类中使用,说明的成员可以在该类中使用,也可以在其也可以在其派生类派生类中使用,但其他函数或类中使用,但其他函数或类不能直接访问不能直接访问 protected protected 成员。成员。53.1 3.1 类类例如:例如:class firstclass private: int x; /只能在只能在 firstclass类中使用类中使用 public: void set(int xx) x=xx; int get() return x; ; 63.1 3.1 类类例例3.1 3.1 设计复数类设计复数类 class complex float real, imag; public

4、: complex(float x=0, float y=0)real = x; imag = y; complex() complex add(complex x) complex z; z.real = real + x.real; z.imag = imag + x.imag; return z; ;73.1 3.1 类类1.1.成员变量成员变量成员变量的定义成员变量的定义 成员变量可用任何成员变量可用任何c+c+的基本数据类型、用户的基本数据类型、用户自定义数据类型、自定义数据类型、c+c+的基本类类型或用户自的基本类类型或用户自定义的类类型定义。定义的类类型定义。 成员变量定义不能递

5、归,即不能用自身类的实成员变量定义不能递归,即不能用自身类的实例化对象作为该类的成员变量。如下定义类例化对象作为该类的成员变量。如下定义类a a是是错误错误的:的: class aclass a private: private: a x; a x; ; ;83.1 3.1 类类1.1.成员变量成员变量 成员变量的初始化成员变量的初始化 成员变量不能在定义时初始化成员变量不能在定义时初始化,成员变量的初,成员变量的初始化是在具体对象创建时由构造函数完成的。始化是在具体对象创建时由构造函数完成的。 类的定义仅仅给出成员的类型,并不实际分配类的定义仅仅给出成员的类型,并不实际分配存储空间,只有创建

6、了该类的一个实例(具体存储空间,只有创建了该类的一个实例(具体对象)后,才能为对象内部的成员分配空间。对象)后,才能为对象内部的成员分配空间。93.1 3.1 类类1.1. 成员变量成员变量 成员变量的初始化成员变量的初始化例如:例如:class c private: int n=0; /error int rint=0; /error ;103.1 3.1 类类1.1.成员函数成员函数基本概念基本概念成员函数是声明在类内的一种函数,成员函数是声明在类内的一种函数,publicpublic访问访问权限的成员函数是一类对外部程序的公共接口。权限的成员函数是一类对外部程序的公共接口。成员函数可以访

7、问同一个类中的任何访问权限的成员函数可以访问同一个类中的任何访问权限的成员变量,也可以调用同一个类中的任何访问权限成员变量,也可以调用同一个类中的任何访问权限的其他成员函数,但构造函数和析构函数除外。的其他成员函数,但构造函数和析构函数除外。成员函数包括两种:成员函数包括两种: 构造函数和析构函数构造函数和析构函数 其它成员函数其它成员函数113.1 3.1 类类1.1. 成员函数成员函数 成员函数的定义成员函数的定义内联函数形式内联函数形式1 1class aclass a 返回类型返回类型 成员函数名(形参表)成员函数名(形参表) 函数体;函数体; ;例如:例如:123.1 3.1 类类c

8、lass complex float real; float imag; public: complex(float x=0, float y=0)real = x; imag = y; complex() complex add(complex x) complex z; z.real = real + x.real; z.imag = imag + x.imag; return z; ;133.1 3.1 类类1.1. 成员函数成员函数 成员函数的定义成员函数的定义内联函数形式内联函数形式2 2class aclass a 返回类型返回类型 成员函数名成员函数名( (形参表形参表););i

9、nline inline 返回类型返回类型 类名类名: 成员函数名成员函数名( (形参表形参表) ) 函数体;函数体; 例如:例如:143.1 3.1 类类1.1. 夺夺class complex float real; float imag; public: complex(float x=0, float y=0)real = x; imag = y; complex() complex add(complex x);inline complex complex:add(complex x)153.1 3.1 类类1.1. 成员函数成员函数 成员函数的定义成员函数的定义外联函数形式:外联函

10、数形式:class aclass a 返回类型返回类型 成员函数名成员函数名( (形参表形参表););返回类型返回类型 类名类名: 成员函数名成员函数名( (形参表形参表) ) 函数体;函数体; 163.1 3.1 类类3.3. 成员函数成员函数成员函数重载成员函数重载基本概念基本概念成员函数重载就是允许多个功能类似的成员成员函数重载就是允许多个功能类似的成员函数使用同一个函数名。当一个对象收到两函数使用同一个函数名。当一个对象收到两个或多个相同消息时,则因调用成员函数时个或多个相同消息时,则因调用成员函数时的参数个数或参数类型不同,而有不同的操的参数个数或参数类型不同,而有不同的操作结果。作

11、结果。173.1 3.1 类类3.3.成员函数成员函数 成员函数重载成员函数重载 成员函数重载的设计要求成员函数重载的设计要求 重载的多个成员函数之间参数个数或类型重载的多个成员函数之间参数个数或类型要有所不同。要有所不同。 函数返回值类型不同不能作为重载依据。函数返回值类型不同不能作为重载依据。 构造函数和所有成员函数都可以重载。构造函数和所有成员函数都可以重载。183.1 3.1 类类1.1. 构造函数构造函数 基本概念基本概念构造函数是一个特殊的成员函数,主要用于构造函数是一个特殊的成员函数,主要用于为对象分配空间为对象分配空间。每当创建对象时,系统都自动调用构造函数,每当创建对象时,系

12、统都自动调用构造函数,用来用来设置该对象的成员变量的初始数据值设置该对象的成员变量的初始数据值。193.1 3.1 类类1.1.构造函数构造函数构造函数声明构造函数声明构造函数的访问权限一定是构造函数的访问权限一定是publicpublic。构造函数名一定要和类名相同。构造函数名一定要和类名相同。构造函数不能有返回类型,也不能是构造函数不能有返回类型,也不能是voidvoid类型。类型。例如:例如:class complex float real; float imag; public: complex(float x=0, float y=0) real = x; imag = y; ;20

13、3.1 3.1 类类1.1.构造函数构造函数构造函数重载构造函数重载一个类中可以有多个参数个数或参数类型不同的一个类中可以有多个参数个数或参数类型不同的构造函数。构造函数。1)1) 缺省参数的构造函数缺省参数的构造函数无参数或参数全为无参数或参数全为缺省值缺省值. .例如:例如:complex();complex();complex(doublecomplex(double r = 0.0, double i = 0.0); r = 0.0, double i = 0.0);213.1 3.1 类类1.1. 构造函数构造函数 构造函数重载构造函数重载2)2) 带参构造函数带参构造函数参数中至少

14、有一个不是缺参数中至少有一个不是缺省值省值. .例如:例如:complex(doublecomplex(double r, double i); r, double i);223.1 3.1 类类1.1. 构造函数构造函数 构造函数重载构造函数重载3)3) 拷贝构造函数拷贝构造函数参数是一个已有初始化数参数是一个已有初始化数值的值的对象对象。作用:将用作实参的对象的每一个成员变量的作用:将用作实参的对象的每一个成员变量的值都复制到新建的同类对象中。值都复制到新建的同类对象中。233.1 3.1 类类4.4. 构造函数构造函数 拷贝构造函数拷贝构造函数自定义拷贝构造函数自定义拷贝构造函数一般形式

15、为:一般形式为:classname(constclassname(const classnameclassname &ob) &ob) 例如:例如:class point int x, y;public: point(int a, int b) x = a; y = b; point(const point &p) x = p.x; y = p.y;243.1 3.1 类类4.4.构造函数构造函数拷贝构造函数拷贝构造函数 缺省拷贝构造函数缺省拷贝构造函数如果没有编写自定义的拷贝构造函数,如果没有编写自定义的拷贝构造函数,c+c+会会自动地将一个已存在的对象复制给新对象。自动地将一个已存在的对象

16、复制给新对象。例如:例如:class point int x, y;public: point(int a, int b) x = a; y = b;point p1(30, 40);point p2(p1); point p3 = p1;253.1 3.1 类类4.4.构造函数构造函数拷贝构造函数拷贝构造函数 系统提供默认拷贝构造函数的条件是系统提供默认拷贝构造函数的条件是不存在不存在下下列任意一种情况:列任意一种情况:1)1)类中有类中有constconst成员;成员;2)2)类中有引用类型成员;类中有引用类型成员;3)3)类或它的基类中有私有拷贝构造函类或它的基类中有私有拷贝构造函数。数

17、。263.1 3.1 类类4.4.构造函数构造函数拷贝构造函数拷贝构造函数拷贝构造函数的特点拷贝构造函数的特点 拷贝构造函数名与类同名,不指定函数的返拷贝构造函数名与类同名,不指定函数的返回值类型,具有一般构造函数的所有特性。回值类型,具有一般构造函数的所有特性。 拷贝构造函数只有一个参数,且是对某个对拷贝构造函数只有一个参数,且是对某个对象的引用。象的引用。 每个类都必须有一个拷贝构造函数,如果类每个类都必须有一个拷贝构造函数,如果类中没有定义拷贝构造函数,编译系统会自动中没有定义拷贝构造函数,编译系统会自动生成一个缺省拷贝构造函数,作为该类的公生成一个缺省拷贝构造函数,作为该类的公有成员。

18、有成员。273.1 3.1 类类4.4. 构造函数构造函数 拷贝构造函数拷贝构造函数举例举例class date int day;public: date(int d=0): day(d) date(date &d) day = d.day; date(void) void printdate(void) const coutdayendl; ; date today(23);date someday;date someday2(today);283.1 3.1 类类1.1. 构造函数构造函数 初始化表初始化表初始化表的格式初始化表的格式成员变量名成员变量名( (初始值初始值), ), , ,

19、 成员变量名成员变量名( (初始值初始值) )其位置在构造函数头部的后面,中间用其位置在构造函数头部的后面,中间用“:”与构造函数头部连接的部分称为初始化表与构造函数头部连接的部分称为初始化表。293.1 3.1 类类1.1.构造函数构造函数初始化表初始化表 为什么要使用初始化表为什么要使用初始化表? ?初始化只能初始化只能在构造函数中在构造函数中进行,但对于常进行,但对于常量类型量类型(const)(const)和引用类型和引用类型(&)(&)的成员变量的成员变量以及对象成员,又不能在构造函数中用赋以及对象成员,又不能在构造函数中用赋值语句直接赋值,因此值语句直接赋值,因此c+c+提供了初始

20、化表提供了初始化表的的置初值置初值方式方式 。303.1 3.1 类类1.1.构造函数构造函数初始化表初始化表初始化表中成员变量的初始化顺序初始化表中成员变量的初始化顺序不论在初始化表中用什么顺序初始化类的成不论在初始化表中用什么顺序初始化类的成员,编译器都会按成员在类定义时声明的顺员,编译器都会按成员在类定义时声明的顺序做初始化。所以初始化表的顺序实际不起序做初始化。所以初始化表的顺序实际不起作用,但打乱顺序会造成阅读和理解上的混作用,但打乱顺序会造成阅读和理解上的混淆。淆。例如:例如:313.1 3.1 类类#include class a int x; int ℞ const fl

21、oat pi;public: a(int x1):rx(x),pi(3.14) x = x1; void print() coutx=xendl; coutrx=rxendl; coutpi=piendl; ;void main()a a(10);a.print();程序运行结果:程序运行结果:x=10rx=10pi=3.14323.1 3.1 类类1.1.析构函数析构函数基本概念基本概念在一个类中,也可以存在用在一个类中,也可以存在用newnew运算符动态申请内存空运算符动态申请内存空间的语句。这种内存空间是在外部程序创建对象的过间的语句。这种内存空间是在外部程序创建对象的过程中动态进行的,

22、系统无法知道其大小和具体地址,程中动态进行的,系统无法知道其大小和具体地址,这些动态申请的内存空间也不会随着外部程序对象占这些动态申请的内存空间也不会随着外部程序对象占用空间的释放而自动释放。用空间的释放而自动释放。 析构函数是一个特殊的成员函数,每当程序中创建的析构函数是一个特殊的成员函数,每当程序中创建的对象脱离其作用域时(例如对象所在的函数已调用完对象脱离其作用域时(例如对象所在的函数已调用完毕),系统将自动调用析构函数。析构函数一般用来毕),系统将自动调用析构函数。析构函数一般用来做做“清理善后清理善后” ” 的工作,主要是完成动态申请内存空的工作,主要是完成动态申请内存空间的释放,以

23、及其他一些扫尾工作。间的释放,以及其他一些扫尾工作。333.1 3.1 类类1.1. 析构函数析构函数 析构函数的说明析构函数的说明类名类名();();析构函数不能带任何参数,不能有返回析构函数不能带任何参数,不能有返回类型(类型(voidvoid也不允许)。也不允许)。一个类中只能有一个类中只能有一个一个析构函数。析构函数。343.1 3.1 类类1.1. 析构函数析构函数 注意事项注意事项如果类中用如果类中用newnew运算符动态申请了内存空间,运算符动态申请了内存空间,则该类的析构函数一定不能为空。此时,析则该类的析构函数一定不能为空。此时,析构函数应该设计用构函数应该设计用delete

24、delete运算符释放动态申运算符释放动态申请的内存空间。另外,凡是调用请的内存空间。另外,凡是调用deletedelete运算运算符时,系统也将自动调用析构函数。符时,系统也将自动调用析构函数。如果需要析构函数完成一些特殊的扫尾工作,如果需要析构函数完成一些特殊的扫尾工作,则这些工作可以在析构函数中完成。则这些工作可以在析构函数中完成。353.1 3.1 类类1.1. 析构函数析构函数例例3.4 3.4 设计一个简单的动态数组类。设计一个简单的动态数组类。class array double *arr; int size;public: array(int sz=100); array(vo

25、id);;363.1 3.1 类类array:array(int sz) if(sz=0) cout“参数错参数错!”endl; exit(0); size = sz; arr = new doublesize;array:array(void) deletearr; void main() array a(10); 373.1 3.1 类类1.1.constconst修饰符修饰符constconst修饰符的作用修饰符的作用 用用constconst来定义变量,如来定义变量,如: :const const intint maxsizemaxsize = 100 = 100; 宏定义命令定义的常

26、量的作用域是从定义处宏定义命令定义的常量的作用域是从定义处到文件结束,或到用宏定义命令到文件结束,或到用宏定义命令# #undefundef取消取消其定义时为止;其定义时为止; 用用constconst定义变量可在文件内、函数内或块定义变量可在文件内、函数内或块内。内。383.1 3.1 类类1.1.constconst修饰符修饰符constconst修饰符的作用修饰符的作用 修饰成员函数参数修饰成员函数参数当成员函数的某个参数修饰为当成员函数的某个参数修饰为constconst时,表示时,表示该参数在成员函数内不会,也不能被修改。该参数在成员函数内不会,也不能被修改。 修饰成员函数修饰成员函

27、数当当constconst修饰成员函数时,关键字修饰成员函数时,关键字constconst通常通常放在成员函数定义的最后面,表示限制该成放在成员函数定义的最后面,表示限制该成员函数只能读取而不能修改当前对象的成员员函数只能读取而不能修改当前对象的成员变量。变量。393.2 3.2 对象对象1.1. 类与对象的关系类与对象的关系 在在c+c+中,类是创建对象时的模板,对象是类中,类是创建对象时的模板,对象是类的实际变量,也称为类的实例。的实际变量,也称为类的实例。 对象是一个引用类型,对象名是指向系统所分对象是一个引用类型,对象名是指向系统所分配内存空间首地址的引用(或别名)。配内存空间首地址的

28、引用(或别名)。例如:例如:complex x(1, 2);complex x(1, 2);成员函数指针成员函数指针2 21 1x403.2 3.2 对象对象2.2. 对象的定义对象的定义利用构造函数创建对象有两种方法:利用构造函数创建对象有两种方法: () * * = new = new ()例如:创建复数类例如:创建复数类complexcomplex的一个对象的一个对象x xcomplex x(1, 2); complex x(1, 2); 或或 complex complex * *x = new complex(1, 2);x = new complex(1, 2);413.2 3.2

29、 对象对象3.3.constconst对象对象c+c+语言可以限定对象为语言可以限定对象为constconst。constconst对象只能通过构造函数有一次初始化赋对象只能通过构造函数有一次初始化赋值。值。const complex x(1, 2);const complex x(1, 2);x.setreal(10);x.setreal(10);/error/errorx.setimage(20);x.setimage(20);/error/errorconstconst对象只能调用返回值类型限定为对象只能调用返回值类型限定为constconst的的公有成员函数,不能调用非公有成员函数,不

30、能调用非constconst的成员函数。的成员函数。423.2 3.2 对象对象4.4. 类成员的访问权限对对象操作的限制类成员的访问权限对对象操作的限制 若某个类成员定义为若某个类成员定义为publicpublic访问权限,则允许访问权限,则允许外部程序访问该成员。外部程序访问该成员。 若某个类成员定义为若某个类成员定义为privateprivate访问权限,则只访问权限,则只允许该类本身的成员函数访问这些成员,即为允许该类本身的成员函数访问这些成员,即为类的封装或信息隐藏。类的封装或信息隐藏。例如:例如:complex x(1, 2), y(3, 4), z1, z2;complex x(

31、1, 2), y(3, 4), z1, z2;z1=x.add(yz1=x.add(y););x.realx.real = 10; = 10; /error/error433.2 3.2 对象对象1.1. 类成员的访问权限对对象操作的限制类成员的访问权限对对象操作的限制 外部程序对私有成员变量的访问通过设计相应外部程序对私有成员变量的访问通过设计相应的的publicpublic成员函数来实现。成员函数来实现。例例3.8 3.8 重新设计复数类。重新设计复数类。public:public:float float getreal(voidgetreal(void) const;) const;fl

32、oat float getimag(voidgetimag(void) const;) const;void void setreal(constsetreal(const float x); float x);void void setimag(constsetimag(const float y); float y);通过通过setset方法和方法和getget方法,可以增强对类中成员方法,可以增强对类中成员变量权限设置的灵活性。变量权限设置的灵活性。443.2 3.2 对象对象5.5.对象的种类对象的种类对象按作用域不同可分为四种:对象按作用域不同可分为四种: 全局对象全局对象在主程序执

33、行之前构造。在主程序执行之前构造。 局部对象局部对象 块对象块对象 动态对象动态对象执行运算符执行运算符newnew时被创建时被创建; ;执行运算符执行运算符deletedelete时被撤消。时被撤消。453.2 3.2 对象对象5.5.对象的种类对象的种类例例: : 用用newnew运算符创建运算符创建complexcomplex类的对象类的对象x,x,对象对象y y。complex complex * *x = new complex(1,2);x = new complex(1,2);complex complex * *y;y;y = new complex(3,4);y = new

34、complex(3,4);463.2 3.2 对象对象6.6.对象的引用对象的引用对象的引用是指对对象的引用是指对对象成员的引用对象成员的引用,外部程序外部程序(外部(外部函数)只能通过向该对象发消息才能访问该对象的函数)只能通过向该对象发消息才能访问该对象的公公有有成员变量和成员函数。成员变量和成员函数。一般引用格式如下:一般引用格式如下:使用点运算符使用点运算符(.)(.):对象名对象名. .成员成员complex x(1, 2); complex x(1, 2); x.setreal(10);x.setreal(10);使用指针运算符(使用指针运算符(-):):指向对象的指针指向对象的指

35、针-成员成员complex complex * *x = new complex(1, 2);x = new complex(1, 2);complex y(3, 4), z;complex y(3, 4), z;z = x-z = x-add(yadd(y););473.3 3.3 对象成员变量对象成员变量1.1. 对象模式中的整体对象模式中的整体-部分模式部分模式 表示了一个整体对象概念是由若干个部分对象表示了一个整体对象概念是由若干个部分对象概念以某种方式组合构成的。概念以某种方式组合构成的。 用面向对象程序语言表达即先定义表示部分概用面向对象程序语言表达即先定义表示部分概念的类,再定义

36、表示整体对象的类,并在其中念的类,再定义表示整体对象的类,并在其中定义部分对象类类型的成员变量。定义部分对象类类型的成员变量。 对象成员变量对象成员变量若一个类的成员变量是另一个类的对象,则若一个类的成员变量是另一个类的对象,则该成员变量称对象成员变量。该成员变量称对象成员变量。483.3 3.3 对象成员变量对象成员变量例例3.10 3.10 设计一个线段类。设计一个线段类。class pointprivate: int x; int y;public: point(int a, int b): x(a), y(b) point(point &c): x(c.x), y(c.y) point

37、(void) ;class lineprivate: point a;/对象成员变量对象成员变量 point b;493.3 3.3 对象成员变量对象成员变量2.2. 外层类的构造函数外层类的构造函数 如何实现外层类的构造函数?如何对其子对象如何实现外层类的构造函数?如何对其子对象进行初始化?进行初始化? 初始化具体有两种方法:初始化具体有两种方法:显式调用相应的拷贝构造函数为子对象显式调用相应的拷贝构造函数为子对象赋初值。例赋初值。例3.113.11的构造函数的构造函数1 1即为此种设即为此种设计方法。计方法。显式调用相应的的构造函数为子对象赋显式调用相应的的构造函数为子对象赋初值。例初值。

38、例3.113.11的构造函数的构造函数2 2即为此种设计即为此种设计方法。方法。503.3 3.3 对象成员变量对象成员变量例例3.11 3.11 设计一个线段类。设计一个线段类。class pointprivate: int x; int y;public: point(int a, int b):x(a), y(b) point(point &c):x(c.x), y(c.y) point(void) int getx(void) const return x; int gety(void) const return y; ;513.3 3.3 对象成员变量对象成员变量class line

39、private: point a;/对象成员变量对象成员变量 point b;public: line(point &aa, point &bb):a(aa), b(bb) line(int a1, int b1, int a2, int b2) :a(a1, b1), b(a2, b2) line(void) void showa(void) const cout“(“a.getx()“,”a.gety()“)”endl; ;523.3 3.3 对象成员变量对象成员变量void main() point a(10, 10), b(50, 50); line myline1(a, b); my

40、line1.showa(): myline1.showb(); line myline2(1, 1, 5, 5); myline2.showa(); myline2.showb();程序运行结果:程序运行结果:(10, 10)(50, 50)(1, 1)(5, 5)533.3 3.3 对象成员变量对象成员变量1.1. 构造函数和析构函数的调用过程构造函数和析构函数的调用过程 对于整体对于整体部分对象模式,部分对象模式, 当创建整体类对象时,要通过显式调用部分类的当创建整体类对象时,要通过显式调用部分类的构造函数完成对子对象的初始化赋值;构造函数完成对子对象的初始化赋值; 当所创建整体类对象超出

41、其作用域要被撤销时,当所创建整体类对象超出其作用域要被撤销时,系统要自动调用部分类的析构函数。系统要自动调用部分类的析构函数。543.3 3.3 对象成员变量对象成员变量1.1. 构造函数和析构函数自动调用过程构造函数和析构函数自动调用过程例:以例:以pointpoint类和类和lineline类为例子测试构造函数和析类为例子测试构造函数和析构函数自动调用过程。构函数自动调用过程。class point int x; int y;public: point(int a, int b):x(a), y(b) cout“类类point构造构造函数调用函数调用”endl; point(point &

42、p):x(p.x), y(p.y)/拷贝构造函数拷贝构造函数 cout“类类point拷贝拷贝构造函数调用构造函数调用”endl; point(void) cout“类类point析构函数调用析构函数调用”endl; ;553.3 3.3 对象成员变量对象成员变量1.1. 构造函数和析构函数自动调用过程构造函数和析构函数自动调用过程class line point a; point b; /对象成员变量对象成员变量public: line(int a1,int b1,int a2,int b2):a(a1, b1), b(a2, b2) cout“类类line构造构造函数函数1 1调用调用”e

43、ndl; line(point &aa, point &bb):a(aa), b(bb) cout“类类line构造构造函数函数2 2调用调用”endl; line(void) cout“类类line析析构函数调用构函数调用”endl ; ; 563.3 3.3 对象成员变量对象成员变量void main(void) line myline(1, 1, 5, 5); point a(1, 1), b(5, 5); line myline2(a, b);运行结果:运行结果:类类pointpoint构造函数调用构造函数调用类类pointpoint构造函数调用构造函数调用类类lineline构造函数

44、构造函数1 1调用调用类类pointpoint构造函数调用构造函数调用类类pointpoint构造函数调用构造函数调用类类pointpoint拷贝构造函数调用拷贝构造函数调用类类pointpoint拷贝构造函数调用拷贝构造函数调用类类lineline构造函数构造函数2 2调用调用类类lineline析构函数调用析构函数调用类类pointpoint析构函数调用析构函数调用类类pointpoint析构函数调用析构函数调用类类pointpoint析构函数调用析构函数调用类类pointpoint析构造函数调用析构造函数调用类类lineline析构函数调用析构函数调用类类pointpoint析构函数调用

45、析构函数调用类类pointpoint析构函数调用析构函数调用573.4 3.4 内部类内部类1.1.基本概念基本概念当类当类a a完全是为类完全是为类b b服务时,此时外部程序不需要,服务时,此时外部程序不需要,也没有必要创建类也没有必要创建类a a的对象时,类的对象时,类a a可以定义在类可以定义在类b b的内部。的内部。内部类内部类 把定义在另一个类中的类(如类把定义在另一个类中的类(如类a a)称做内部)称做内部类。类。外部类外部类 把封装有内部类的类(如类把封装有内部类的类(如类b b)称做外部类。)称做外部类。583.4 3.4 内部类内部类例例3.13 3.13 设计线段类,把设计

46、线段类,把pointpoint类定义为类定义为lineline类的类的内部类。内部类。class lineclass point public: int x, y; point(int inix=0, int iniy=0):x(inix), y(iniy) point(void) ;private: point a, b;593.4 3.4 内部类内部类public: line(int x1=0, int y1=0, int x2=0, int y2=0): a(x1, y1), b(x2, y2) line(void) void showa(void) const cout“a point

47、 is:(” a.x“,” a.y“)”endl; void showb(void) const cout“b point is:(” b.x“,” b.y“)”endl; ;603.4 3.4 内部类内部类1.1. 说明说明 内部类对外部程序是不可见的。内部类对外部程序是不可见的。 外部类无法直接访问内部类的私有成员。外部类无法直接访问内部类的私有成员。 内部类无法直接访问外部类的私有成员。内部类无法直接访问外部类的私有成员。line myline(0, 10, 50, 50);myline.showa();myline.showb();/point a(10, 10), b(50, 50)

48、; /error613.5 static 3.5 static 成员成员1.1. 问题引入问题引入 在面向对象程序设计时,有些特殊的成员不是在面向对象程序设计时,有些特殊的成员不是属于具体的对象,而是属于具体的对象,而是属于整个类属于整个类。 c+c+语言将这些成员定义为语言将这些成员定义为staticstatic来实现,它可来实现,它可以解决同一类的不同对象之间的数据和函数的以解决同一类的不同对象之间的数据和函数的共享问题。共享问题。623.5 static 3.5 static 成员成员1.1.问题引入问题引入应用举例应用举例 假设视频游戏中有人物假设视频游戏中有人物martmart和其他

49、太空人。和其他太空人。 当当martmart知道至少有知道至少有5 5个个martmart存在时,就要攻击存在时,就要攻击其他太空人。其他太空人。 如果如果martmart的人数少于的人数少于5 5个,个, martmart就会胆小而不就会胆小而不敢攻击。因此每个敢攻击。因此每个martmart需要知道需要知道martcountmartcount。问题:问题:c+c+中如何使每个中如何使每个martmart得到得到martcountmartcount值?值?633.5 static 3.5 static 成员成员1.1.问题引入问题引入应用举例应用举例解决方法:解决方法: 在类在类martma

50、rt中提供一个中提供一个static static martcountmartcount成员成员变量,使其为类共享数据。变量,使其为类共享数据。 c+c+只需维护只需维护martcountmartcount的一个静态副本。的一个静态副本。643.5 static 3.5 static 成员成员2.2. staticstatic成员变量成员变量 定义为定义为staticstatic的成员变量称作的成员变量称作staticstatic成员变量。成员变量。 staticstatic成员变量可定义为成员变量可定义为privateprivate,也可定义,也可定义为为publicpublic。 stat

51、icstatic成员变量不能限定为成员变量不能限定为constconst,因为,因为constconst成员变量只能一次赋值,而成员变量只能一次赋值,而staticstatic成员变量可成员变量可能需要多次赋值。能需要多次赋值。653.5 static 3.5 static 成员成员2.2. staticstatic成员变量成员变量 staticstatic成员变量和非成员变量和非staticstatic成员变量的差别成员变量的差别 staticstatic成员变量是在编译时分配存储空间,成员变量是在编译时分配存储空间,直到整个程序执行完才撤消。直到整个程序执行完才撤消。 staticstat

52、ic成员变量的初始化是在编译时进行的,成员变量的初始化是在编译时进行的,一般在定义一般在定义staticstatic成员变量时要给出初始值。成员变量时要给出初始值。663.5 static 3.5 static 成员成员3.3. staticstatic成员变量的初始化成员变量的初始化 staticstatic成员变量属于整个类,成员变量属于整个类,为该类的所有对为该类的所有对象所共享象所共享。 必须在定义该类(含有必须在定义该类(含有staticstatic成员变量)的任成员变量)的任何对象之前何对象之前(或者说在全局作用域内),单独(或者说在全局作用域内),单独初始化初始化staicsta

53、ic成员变量。成员变量。 初始化格式:初始化格式: : = = ; ; 引用引用staticstatic成员变量的语法形式为:成员变量的语法形式为: : 673.5 static 3.5 static 成员成员4.4. staticstatic成员函数成员函数 staticstatic成员函数专门用来实现对成员函数专门用来实现对staticstatic成员变成员变量的访问,它是整个类的成员函数,为该类的量的访问,它是整个类的成员函数,为该类的所有对象所共享。所有对象所共享。 staticstatic成员函数调用格式:成员函数调用格式: : : (););683.5 static 3.5 sta

54、tic 成员成员例例 3.14 3.14 设计一个职工类,说明设计一个职工类,说明staticstatic成员的使成员的使用方法。用方法。class employee char name30; float salary; static float allsalary;public: employee(char *n, float s) strcpy(name, n); salary = s; allsalary = allsalary+salary; 693.5 static 3.5 static 成员成员 employee(void) allsalary = allsalary salary

55、; static float getallsalary(void) return allsalary; ;/static成员变量的初始化成员变量的初始化float employee:allsalary = 0;703.5 static 3.5 static 成员成员程序运行结果程序运行结果: allsalaryallsalary=600=600void main(void)employee e1(zhang, 100);employee e2(wang, 200);employee e3(li, 300);float all; / static成员函数调用成员函数调用all = employe

56、e:getallsalary();coutallsalary=allendl;71#includeclass martint number;int lift_time;static int martcount;public:mart(int n, int l): number(n), lift_time(l) martcount+;void run();void jump();void attack();static int getcount() return martcount; ;游戏应用设计:游戏应用设计:72int mart:martcount = 0;void main()mart

57、mart1(1, 100), mart(2, 100);coutmart:getcount() this - 成员变量成员变量而在主函数内不能使用对象而在主函数内不能使用对象thisthis指针显式调用指针显式调用成员函数。成员函数。例例3.15 3.15 日期类的设计日期类的设计753.6 3.6 自引用对象指针自引用对象指针thisthisclass date int month; int day; int year;public: date(int month=0, int day=0, int year=0) this-month = month; / (*this).month =

58、month; this-day = day; this-year = year; void printdate(void) const coutmonth“-”day“-”yearthis-数据成员的方式。例如:数据成员的方式。例如:void void printdate(voidprintdate(void) const) const coutcoutmonth; month; 对每个成员函数的调用,加上一个附加的实参对每个成员函数的调用,加上一个附加的实参-被调用对象的地址。被调用对象的地址。today.printdate(&todaytoday.printdate(&today););803.7 3.7 设计举例设计举例例例3.16 3.16 银行贷记卡系统的设计银行贷记卡系统的设计贷记卡是指发卡银行给予持

温馨提示

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

评论

0/150

提交评论