1、1/20/2019,1,C+程序设计教程(第二版),第八章 类 Chapter 8 Class,清华大学出版社 钱 能,1/20/2019,2,类类是一种可以作为交易的概念代码类是自定义的数据类型类与应用程序不同,类的功能虽然独立,但不能独立启动,就象汽车零件那样.类机制要通过编程的方法来维护类的数据表达,值范围和操作并不是简单的,因为要限制一些操作只能让类自己来做,以免发生问题时,无人敢对其负责类机制就是通过语言的规定性来实现一些技术,使类具有数据封装,信息屏蔽,多态等特征,起到数据类型的作用,而达到方便编程的目的.,1/20/2019,3,第八章内容,从结构到类( From Structu
2、re to Class ) 成员函数 ( Member Functions ) 操作符 ( Operators ) 再论程序结构 ( Program Struture Restatement )屏蔽类的实现 ( Shield Class Implementations ) 静态成员 ( Static Members ) 友元 ( Friends ),1/20/2019,4,1. 从结构到类( From Structure to Class ),结构:单纯堆积数据空间构造的类型类:不但描述数据空间,还描述其操作的自定义类型变量:由内部数据类型或衍生的结构类型所产生的实体对象: 由类产生的实体,本
3、质上,变量也是对象,只不过粗糙一点罢了.,1/20/2019,5,2. 成员函数( Functions ),成员函数与普通函数的区别: 成员函数属于类, 成员函数定义是类设计的一部分, 其作用域是类作用域. 而普通函数一般为全局函数 成员函数的操作主体是对象,使用时通过捆绑对象来行使其职责, 而普通函数被调用时没有操作主体,1/20/2019,6,成员函数的内联性 成员函数可以在类内,也可以在类外定义,若在类内定义,则默认为内联函数.但编译器对内联的接受自有其原则.,class Date int year, month, day; public:void set ( int y, int m,
4、 int d ) / 默认内联year=y; month=m; day=d; ; inline bool Date:isLeapYear ( ) / 显式内联return ! ( year%400 ) | !(year%4) ,1/20/2019,7,访问成员函数的方式,对象方式Date d;d.set(2005,12,5);对象指针方式Date* dp = new Date;dp-set(2005,12,5);/ delete dp;,1/20/2019,8,常成员函数与函数的常量参数,常成员函数 对捆绑的对象, 不允许写操作 函数的常量参数 对传递的参数, 不允许写操作 例如:bool D
5、ate:comp(const Date,1/20/2019,9,3. 操作符 ( Operators ),操作符定义就是函数定义,调用操作符就是调用函数,例如:Point operator+(const Point / p + q 等价于 operator+(p, q) 一切自定义操作符都是语言中操作符的重载. 操作符作用:让编译器理解人性化编程代码.从正确性上讲并不是必要的.例如,Java不允许操作符重载,1/20/2019,10,值返回 返回临时表达式的值,例如: Point operator+(const Point ,值返回与引用返回,1/20/2019,11,成员操作符与普通操作符,
6、普通操作符: Point operator+(const Point p + q等价于成员操作符p.operator+(q),或者普通操作符operator(p, q) 两者必居其一.,1/20/2019,12,4. 再论程序结构 ( Program Structure Restatement ),访问控制 成员函数 一般为公有public 公有的成员函数在类的外部可以被使用,即外界可以调用成员函数 数据成员 一般为私有private 私有的数据成员在外部不能被访问,即外界不能访问对象的数据分量,而只能由成员函数内部去处理 公有和私有可任意设定 访问控制public和private是语言提供给
7、程序员的功能,1/20/2019,13,程序结构,类定义作为头文件,如:point.h 类的实现作为独立编译单元,如:point.cpp 使用类的程序作为另一独立编译单元,如:f0809.cpp 类的头文件和类的实现可以作为一个独立的资源提供给编程者 内联的成员函数定义一般放在头文件中头文件中必须使用头文件卫士技术,1/20/2019,14,类作用域与类定义作用域,类定义作用域: 从类定义结束开始,到从外面包围类定义的块结束(若类定义外无包围块,则结束于文件) 使用类的程序员在类定义作用域下编程类作用域: 类定义内部及成员函数定义内部 实现类的程序员在类作用域下编程,1/20/2019,15,
8、5. 屏蔽类的实现 ( Shield Class Implementations ),使用类的应用程序只需要类定义头文件编程 实现类,也只需要类定义头文件,不需要使用类的程序细节 确定了类定义(头文件),便可以从事两方面的编程而互不干涉 类定义成功地屏蔽了类的实现,是类机制的技术体现,1/20/2019,16,6. 静态成员 ( Static Members ),静态数据成员在类作用域中声明,在类定义作用域中定义(一般是在main函数启动之前定义),每个该类对象都共享描述任何对象的共性状态在多文件程序结构中,一般放在类的实现编译单元中,1/20/2019,17,例如: class Studen
9、tstring name; public:static int num;void set(string / 访问静态成员 ,1/20/2019,18,静态成员函数,调用时,不捆绑对象,所以,不能直接操作对象和其成员,若需访问该类对象,必须以参数传递之. 静态成员函数一般设计为公有的,以访问私有静态数据成员为目的. 调用方式是以类名加域操作符:后跟静态成员函数,1/20/2019,19,例如: class Studentstatic int num; / 静态私有成员/. public:/ .static void showNum() coutnum“n”; / 访问静态私有成员 ; int S
10、tudent:num = 0; / 静态数据成员初始化 int main()Student s;s.showNum(); / 可行,但非标准Student:showNum(); / 静态成员函数调用 ,1/20/2019,20,7. 友元 ( Friends ),友元的作用:弥补访问控制符的不足,在外部频繁操作对象(即调用成员函数),引起调用开销的增加时,可以通过直接访问对象的成员(而不是调用成员函数),而使性能明显提高.,1/20/2019,21,例如:矩阵乘向量函数 friend Vector multiply(Matrix 若以普通函数的身份实现,则要大量调用成员函数去访问私有数据成员,而用友元之后,可以直接访问之,1/20/2019,22,友元的另一作用:用在无法成员化的操作符重载中 例如: class Point / friend ostream中的第一操作数为cout,不是Point对象,所以无法在Point类中将操作符成员化,但又想长驱直入地访问Point中的私有数据成员故用友元,