




已阅读5页,还剩84页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1,第3章 类和对象,2,主要内容,类 对象 对象成员变量 内部类 static成员 自引用对象指针this 设计举例,GO,3,3.1 类,类的定义 类是对具有相同属性和相同行为的客观世界的一组相似对象的抽象。 类的定义形式为: class 类名 private: protected: public: ;,类的作用域,4,3.1 类,类的定义 访问权限关键字 private-说明的成员只能在该类中使用,即在类的外面不能直接访问 private 成员,类的默认访问权限为private。 public-说明的成员不但可以在该类中使用,而且其他的函数或类可以直接访问 public成员。 protected-说明的成员可以在该类中使用,也可以在其派生类中使用,但其他函数或类不能直接访问 protected 成员。,5,3.1 类,例如:,class FirstClass private: int x; /只能在 FirstClass类中使用 public: void set(int xx) x=xx; int get() return x; ;,6,3.1 类,例3.1 设计复数类,class Complex float real, 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; ;,7,3.1 类,成员变量 成员变量的定义 成员变量可用任何C+的基本数据类型、用户自定义数据类型、C+的基本类类型或用户自定义的类类型定义。 成员变量定义不能递归,即不能用自身类的实例化对象作为该类的成员变量。如下定义类A是错误的: class A private: A x; ;,8,3.1 类,成员变量 成员变量的初始化 成员变量不能在定义时初始化,成员变量的初始化是在具体对象创建时由构造函数完成的。 类的定义仅仅给出成员的类型,并不实际分配存储空间,只有创建了该类的一个实例(具体对象)后,才能为对象内部的成员分配空间。,9,3.1 类,成员变量 成员变量的初始化 例如: class c private: int n=0; /error int rint=0; /error ;,10,3.1 类,成员函数 基本概念 成员函数是声明在类内的一种函数,public访问权限的成员函数是一类对外部程序的公共接口。 成员函数可以访问同一个类中的任何访问权限的成员变量,也可以调用同一个类中的任何访问权限的其他成员函数,但构造函数和析构函数除外。 成员函数包括两种: 构造函数和析构函数 其它成员函数,11,3.1 类,成员函数 成员函数的定义 内联函数形式1 class A 返回类型 成员函数名(形参表) 函数体; ; 例如:,12,3.1 类,class 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; ;,13,3.1 类,成员函数 成员函数的定义 内联函数形式2 class A 返回类型 成员函数名(形参表); ; inline 返回类型 类名: 成员函数名(形参表) 函数体; 例如:,14,3.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) ,15,3.1 类,成员函数 成员函数的定义 外联函数形式: class A 返回类型 成员函数名(形参表); ; 返回类型 类名: 成员函数名(形参表) 函数体; ,16,3.1 类,成员函数 成员函数重载 基本概念 成员函数重载就是允许多个功能类似的成员函数使用同一个函数名。当一个对象收到两个或多个相同消息时,则因调用成员函数时的参数个数或参数类型不同,而有不同的操作结果。,17,3.1 类,成员函数 成员函数重载 成员函数重载的设计要求 重载的多个成员函数之间参数个数或类型要有所不同。 函数返回值类型不同不能作为重载依据。 构造函数和所有成员函数都可以重载。,18,3.1 类,构造函数 基本概念 构造函数是一个特殊的成员函数,主要用于为对象分配空间。 每当创建对象时,系统都自动调用构造函数,用来设置该对象的成员变量的初始数据值。,19,3.1 类,构造函数 构造函数声明 构造函数的访问权限一定是public。 构造函数名一定要和类名相同。 构造函数不能有返回类型,也不能是void类型。 例如:,class Complex float real; float imag; public: Complex(float x=0, float y=0) real = x; imag = y; ;,20,3.1 类,构造函数 构造函数重载 一个类中可以有多个参数个数或参数类型不同的构造函数。 缺省参数的构造函数无参数或参数全为缺省值. 例如: Complex(); Complex(double r = 0.0, double i = 0.0);,21,3.1 类,构造函数 构造函数重载 带参构造函数参数中至少有一个不是缺省值. 例如: Complex(double r, double i);,22,3.1 类,构造函数 构造函数重载 拷贝构造函数参数是一个已有初始化数值的对象。 作用:将用作实参的对象的每一个成员变量的值都复制到新建的同类对象中。,23,3.1 类,构造函数 拷贝构造函数 自定义拷贝构造函数 一般形式为: classname(const classname &ob) 例如:,class point int x, y; public: point(int a, int b) x = a; y = b; point(const point ,24,3.1 类,构造函数 拷贝构造函数 缺省拷贝构造函数 如果没有编写自定义的拷贝构造函数,C+会自动地将一个已存在的对象复制给新对象。 例如:,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;,25,3.1 类,构造函数 拷贝构造函数 系统提供默认拷贝构造函数的条件是不存在下列任意一种情况: 类中有const成员; 类中有引用类型成员; 类或它的基类中有私有拷贝构造函数。,26,3.1 类,构造函数 拷贝构造函数 拷贝构造函数的特点 拷贝构造函数名与类同名,不指定函数的返回值类型,具有一般构造函数的所有特性。 拷贝构造函数只有一个参数,且是对某个对象的引用。 每个类都必须有一个拷贝构造函数,如果类中没有定义拷贝构造函数,编译系统会自动生成一个缺省拷贝构造函数,作为该类的公有成员。,27,3.1 类,构造函数 拷贝构造函数 举例,class Date int day; public: Date(int d=0): day(d) Date(Date ,Date today(23); Date someDay; Date someDay2(today);,28,3.1 类,构造函数 初始化表 初始化表的格式 成员变量名(初始值), , 成员变量名(初始值) 其位置在构造函数头部的后面,中间用“:”与构造函数头部连接的部分称为初始化表。,29,3.1 类,构造函数 初始化表 为什么要使用初始化表? 初始化只能在构造函数中进行,但对于常量类型(const)和引用类型(&)的成员变量以及对象成员,又不能在构造函数中用赋值语句直接赋值,因此C+提供了初始化表的置初值方式 。,30,3.1 类,构造函数 初始化表 初始化表中成员变量的初始化顺序 不论在初始化表中用什么顺序初始化类的成员,编译器都会按成员在类定义时声明的顺序做初始化。所以初始化表的顺序实际不起作用,但打乱顺序会造成阅读和理解上的混淆。 例如:,31,3.1 类,#include class A int x; int ,void main() A a(10); a.print(); ,程序运行结果: x=10 rx=10 pi=3.14,32,3.1 类,析构函数 基本概念 在一个类中,也可以存在用new运算符动态申请内存空间的语句。这种内存空间是在外部程序创建对象的过程中动态进行的,系统无法知道其大小和具体地址,这些动态申请的内存空间也不会随着外部程序对象占用空间的释放而自动释放。 析构函数是一个特殊的成员函数,每当程序中创建的对象脱离其作用域时(例如对象所在的函数已调用完毕),系统将自动调用析构函数。析构函数一般用来做“清理善后” 的工作,主要是完成动态申请内存空间的释放,以及其他一些扫尾工作。,33,3.1 类,析构函数 析构函数的说明 类名(); 析构函数不能带任何参数,不能有返回类型(void也不允许)。 一个类中只能有一个析构函数。,34,3.1 类,析构函数 注意事项 如果类中用new运算符动态申请了内存空间,则该类的析构函数一定不能为空。此时,析构函数应该设计用delete运算符释放动态申请的内存空间。另外,凡是调用delete运算符时,系统也将自动调用析构函数。 如果需要析构函数完成一些特殊的扫尾工作,则这些工作可以在析构函数中完成。,35,3.1 类,析构函数 例3.4 设计一个简单的动态数组类。,class Array double *arr; int size; public: Array(int sz=100); Array(void); ;,36,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); ,37,3.1 类,const修饰符 const修饰符的作用 用const来定义变量,如: const int maxsize = 100; 宏定义命令定义的常量的作用域是从定义处到文件结束,或到用宏定义命令#undef取消其定义时为止; 用const定义变量可在文件内、函数内或块内。,38,3.1 类,const修饰符 const修饰符的作用 修饰成员函数参数 当成员函数的某个参数修饰为const时,表示该参数在成员函数内不会,也不能被修改。 修饰成员函数 当const修饰成员函数时,关键字const通常放在成员函数定义的最后面,表示限制该成员函数只能读取而不能修改当前对象的成员变量。,39,3.2 对象,类与对象的关系 在C+中,类是创建对象时的模板,对象是类的实际变量,也称为类的实例。 对象是一个引用类型,对象名是指向系统所分配内存空间首地址的引用(或别名)。 例如:complex x(1, 2);,40,3.2 对象,对象的定义 利用构造函数创建对象有两种方法: () * = new () 例如:创建复数类Complex的一个对象x Complex x(1, 2); 或 Complex *x = new Complex(1, 2);,41,3.2 对象,const对象 C+语言可以限定对象为const。 const对象只能通过构造函数有一次初始化赋值。 const Complex x(1, 2); x.setReal(10); /error x.setImage(20); /error const对象只能调用返回值类型限定为const的公有成员函数,不能调用非const的成员函数。,42,3.2 对象,类成员的访问权限对对象操作的限制 若某个类成员定义为public访问权限,则允许外部程序访问该成员。 若某个类成员定义为private访问权限,则只允许该类本身的成员函数访问这些成员,即为类的封装或信息隐藏。 例如: Complex x(1, 2), y(3, 4), z1, z2; z1=x.Add(y); x.real = 10; /error,43,3.2 对象,类成员的访问权限对对象操作的限制 外部程序对私有成员变量的访问通过设计相应的public成员函数来实现。 例3.8 重新设计复数类。 public: float getReal(void) const; float getImag(void) const; void setReal(const float x); void setImag(const float y); 通过set方法和get方法,可以增强对类中成员变量权限设置的灵活性。,44,3.2 对象,对象的种类 对象按作用域不同可分为四种: 全局对象 在主程序执行之前构造。 局部对象 块对象 动态对象 执行运算符new时被创建; 执行运算符delete时被撤消。,45,3.2 对象,对象的种类 例: 用new运算符创建Complex类的对象x,对象y。 Complex *x = new Complex(1,2); Complex *y; y = new Complex(3,4);,46,3.2 对象,对象的引用 对象的引用是指对对象成员的引用,外部程序(外部函数)只能通过向该对象发消息才能访问该对象的公有成员变量和成员函数。 一般引用格式如下: 使用点运算符(.):对象名.成员 Complex x(1, 2); x.setReal(10); 使用指针运算符(-):指向对象的指针-成员 Complex *x = new Complex(1, 2); Complex y(3, 4), z; z = x-Add(y);,47,3.3 对象成员变量,对象模式中的整体-部分模式 表示了一个整体对象概念是由若干个部分对象概念以某种方式组合构成的。 用面向对象程序语言表达即先定义表示部分概念的类,再定义表示整体对象的类,并在其中定义部分对象类类型的成员变量。 对象成员变量 若一个类的成员变量是另一个类的对象,则该成员变量称对象成员变量。,48,3.3 对象成员变量,例3.10 设计一个线段类。,class Point private: int x; int y; public: Point(int a, int b): x(a), y(b) Point(Point ,class Line private: Point a; /对象成员变量 Point b; ;,49,3.3 对象成员变量,外层类的构造函数 如何实现外层类的构造函数?如何对其子对象进行初始化? 初始化具体有两种方法: 显式调用相应的拷贝构造函数为子对象赋初值。例3.11的构造函数1即为此种设计方法。 显式调用相应的的构造函数为子对象赋初值。例3.11的构造函数2即为此种设计方法。,50,3.3 对象成员变量,例3.11 设计一个线段类。,class Point private: int x; int y; public: Point(int a, int b):x(a), y(b) Point(Point ,51,3.3 对象成员变量,class Line private: Point a; /对象成员变量 Point b; public: Line(Point ,52,3.3 对象成员变量,void main() Point a(10, 10), b(50, 50); Line myLine1(a, b); myLine1.ShowA(): myLine1.ShowB(); Line myLine2(1, 1, 5, 5); myLine2.ShowA(); myLine2.ShowB(); ,程序运行结果: (10, 10) (50, 50) (1, 1) (5, 5),53,3.3 对象成员变量,构造函数和析构函数的调用过程 对于整体部分对象模式, 当创建整体类对象时,要通过显式调用部分类的构造函数完成对子对象的初始化赋值; 当所创建整体类对象超出其作用域要被撤销时,系统要自动调用部分类的析构函数。,54,3.3 对象成员变量,构造函数和析构函数自动调用过程 例:以Point类和Line类为例子测试构造函数和析构函数自动调用过程。,class Point int x; int y; public: Point(int a, int b):x(a), y(b) cout“类Point构造函数调用”endl; Point(Point ,55,3.3 对象成员变量,构造函数和析构函数自动调用过程,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调用”endl; Line(Point ,56,3.3 对象成员变量,void main(void) Line myLine(1, 1, 5, 5); Point a(1, 1), b(5, 5); Line myLine2(a, b); ,运行结果: 类Point构造函数调用 类Point构造函数调用 类Line构造函数1调用 类Point构造函数调用 类Point构造函数调用 类Point拷贝构造函数调用 类Point拷贝构造函数调用 类Line构造函数2调用,类Line析构函数调用 类Point析构函数调用 类Point析构函数调用 类Point析构函数调用 类Point析构造函数调用 类Line析构函数调用 类Point析构函数调用 类Point析构函数调用,57,3.4 内部类,基本概念 当类A完全是为类B服务时,此时外部程序不需要,也没有必要创建类A的对象时,类A可以定义在类B的内部。 内部类 把定义在另一个类中的类(如类A)称做内部类。 外部类 把封装有内部类的类(如类B)称做外部类。,58,3.4 内部类,例3.13 设计线段类,把Point类定义为Line类的内部类。,class Line class Point public: int x, y; Point(int iniX=0, int iniY=0):x(iniX), y(iniY) Point(void) ; private: Point a, b;,59,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 is:(” a.x“,” a.y“)”endl; void ShowB(void) const cout“b point is:(” b.x“,” b.y“)”endl; ;,60,3.4 内部类,说明 内部类对外部程序是不可见的。 外部类无法直接访问内部类的私有成员。 内部类无法直接访问外部类的私有成员。,Line myLine(0, 10, 50, 50); myLine.ShowA(); myLine.ShowB(); /Point a(10, 10), b(50, 50); /error,61,3.5 static 成员,问题引入 在面向对象程序设计时,有些特殊的成员不是属于具体的对象,而是属于整个类。 C+语言将这些成员定义为static来实现,它可以解决同一类的不同对象之间的数据和函数的共享问题。,62,3.5 static 成员,问题引入 应用举例 假设视频游戏中有人物Mart和其他太空人。 当Mart知道至少有5个Mart存在时,就要攻击其他太空人。 如果Mart的人数少于5个, Mart就会胆小而不敢攻击。因此每个Mart需要知道MartCount。 问题: C+中如何使每个Mart得到MartCount值?,63,3.5 static 成员,问题引入 应用举例 解决方法: 在类Mart中提供一个static MartCount成员变量,使其为类共享数据。 C+只需维护MartCount的一个静态副本。,64,3.5 static 成员,static成员变量 定义为static的成员变量称作static成员变量。 static成员变量可定义为private,也可定义为public。 static成员变量不能限定为const,因为const成员变量只能一次赋值,而static成员变量可能需要多次赋值。,65,3.5 static 成员,static成员变量 static成员变量和非static成员变量的差别 static成员变量是在编译时分配存储空间,直到整个程序执行完才撤消。 static成员变量的初始化是在编译时进行的,一般在定义static成员变量时要给出初始值。,66,3.5 static 成员,static成员变量的初始化 static成员变量属于整个类,为该类的所有对象所共享。 必须在定义该类(含有static成员变量)的任何对象之前(或者说在全局作用域内),单独初始化staic成员变量。 初始化格式: : = ; 引用static成员变量的语法形式为: :,67,3.5 static 成员,static成员函数 static成员函数专门用来实现对static成员变量的访问,它是整个类的成员函数,为该类的所有对象所共享。 static成员函数调用格式: : ();,68,3.5 static 成员,例 3.14 设计一个职工类,说明static成员的使用方法。,class Employee char name30; float salary; static float allSalary; public: Employee(char *n, float s) strcpy(name, n); salary = s; allSalary = allSalary+salary; ,69,3.5 static 成员,Employee(void) allSalary = allSalary salary; static float GetAllSalary(void) return allSalary; ; /static成员变量的初始化 float Employee:allSalary = 0;,70,3.5 static 成员,程序运行结果: AllSalary=600,void main(void) Employee e1(“zhang“, 100); Employee e2(“wang“, 200); Employee e3(“li“, 300); float all; / static成员函数调用 all = Employee:GetAllSalary(); cout“AllSalary=“allendl; ,71,#include class Mart int 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; ;,游戏应用设计:,72,int Mart:MartCount = 0; void main() Mart mart1(1, 100), mart(2, 100); coutMart:GetCount()endl; ,73,3.6 自引用对象指针this,基本概念 C+中提供了一个特殊的对象指针this指针,也称做自引用对象指针,它指向类对象的开始地址。 当一个对象被创建时,系统将创建这个对象的this指针,并把它初始化为指向该对象。,74,3.6 自引用对象指针this,当前对象成员的表示方法 在成员函数定义内,可显式使用对象this指针调用成员变量。例如: this - 成员变量 而在主函数内不能使用对象this指针显式调用成员函数。 例3.15 日期类的设计,75,3.6 自引用对象指针this,class Date int month; int day; int year; public: Date(int month=0, int day=0, int year=0) this-month = month; / (*this).month = month; this-day = day; this-year = year; void PrintDate(void) const coutmonth“-”day“-”yearendl; ;,76,3.6 自引用对象指针this,void main() Date today(8,23,2005); Date yester(8,22,2005); today.PrintDate(); yester.PrintDate(); ,77,3.6 自引用对象指针this,系统区分不同对象成员变量的方法 对于类成员函数而言,并不是一个对象对应一个单独的成员函数体,而是此类的所有对象共用这个成员函数体。当程序被编译之后, 此成员函数地址即已确定。 问题: 一个类实例化后可生成多个对象,存在多个对象的成员变量,但成员函数体只有一份拷贝。当引用对象的成员函数访问成员变量时,成员函数如何区别属于此类的各个对象的数据?,78,3.6 自引用对象指针this,系统区分不同对象成员变量的方法 解决方法: C+为每个成员函数提供了一个隐含指针- this指针,它是每个成员函数的第一个参数,它的实参是调用该成员函数的对象的this指针。 调用类成员函数时,会将当前对象的this指针传给成员函数。,79,3.6 自引用对象指针this,系统区分不同对象成员变量的方法 编译器对成员函数的编译方法 函数体内所有对类数据成员的访问,都会被转化为this-数据成员的方式。例如: void PrintDate(void) const coutmonth; 对每个成员函数的调用,加上一个附加的实参-被调用对象的地址。 today.PrintDate(,80,3.7 设计举例,例3.16 银行贷记卡系统的设计 贷记卡是指发卡银行给予持卡人一定的信用额度,持卡人可在信用额度内先消费,后还款的信用卡。 设计要求 客户余额的输出采用类似3元3角1分的形式。 允许客户存款、取款和转账,并允许客户取款时透支。 设计一个主程序进行基本情况的演示。,81,3.7 设计举例,设计分析(Rat
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025电信服务合同保障协议
- 2025【合同范本】设备抵押借款合同范本
- 2025员工试用期合同协议书范本
- 2025租房合同版本范文
- 2025购销合同书范本AA:双方权利与义务明确约定
- 2025护工服务合同模板
- 2025年定制、供货合同(2)
- 2025年安全管理人员安全教育培训试题及答案
- 泗洪中考模拟考试试卷及答案
- 2025劳动合同签订试用期限
- 物业投标书样本
- JBT 11699-2013 高处作业吊篮安装、拆卸、使用技术规程
- 屁屁辅助脚本
- 【顺丰集团财务共享中心运作问题与优化建议探析15000字(论文)】
- 中医科室发展规划方案
- 食药环侦知识讲座
- GB/T 19520.21-2023电气和电子设备机械结构482.6 mm(19 in)系列机械结构尺寸第3-109部分:嵌入式计算设备的机箱尺寸
- 纯水管道施工方案
- 山东省海洋知识竞赛(小学组)考试题库大全-上(单选题汇总)
- 一篇入门EPC总承包项目的税务筹划
- 宝安区人民医院药品目录西药
评论
0/150
提交评论