C高级语言程序设计 第七章 类与对象_第1页
C高级语言程序设计 第七章 类与对象_第2页
C高级语言程序设计 第七章 类与对象_第3页
C高级语言程序设计 第七章 类与对象_第4页
C高级语言程序设计 第七章 类与对象_第5页
已阅读5页,还剩95页未读 继续免费阅读

下载本文档

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

文档简介

1、C+高级语言程序设计高级语言程序设计第第7 7章章 类与对象类与对象 北京邮电大学信息与通信工程学院北京邮电大学信息与通信工程学院2022-2-22北京邮电大学信息与通信工程学院-2-类是实现C+面向对象程序设计的基础。面向对象程序设计的基本特点有:抽象、封装、继承和多态,类把数据和函数封装在一起,是C+封装的基本单元。 2022-2-22北京邮电大学信息与通信工程学院-3-7.17.1 类和对象的定义类和对象的定义7.27.2 对象的使用对象的使用7.37.3 构造函数构造函数7.47.4 析构函数析构函数 7.5 7.5 类的静态成员类的静态成员 7.67.6 类成员的保护和使用类成员的保

2、护和使用7.7 7.7 运算符重载运算符重载 7.87.8 类的组合类的组合7.9 7.9 应用举例应用举例7.107.10 面向对象分析和设计面向对象分析和设计 第第7 7章章 类与对象类与对象 7.17.1 类和对象的定义类和对象的定义2022-2-22北京邮电大学信息与通信工程学院-5-7.17.1 类和对象的定义类和对象的定义一个类表示现实生活中的一类事物,比如“学生”,事物有相应的特征或属性,它们就是类的数据成员;事物可能有行为动作,也可能被某些行为动作所操作,这些都用函数来实现,这些函数和类有着不可分割的关系,是构成类的函数成员,或者叫成员函数。在C+中,类实际上相当于一种用户自定

3、义的数据类型。 2022-2-22北京邮电大学信息与通信工程学院-6-对象是一类事物中的一个具体的个体。在定义了类类型后,就可以定义该类型的变量,这个变量就称为类的对象(或实例)。所以,从程序设计的角度来看,对象就相当于变量。 7.17.1 类和对象的定义类和对象的定义2022-2-22北京邮电大学信息与通信工程学院-7-举例:class Student /类的定义private:int id;char20 name;int age;float score;public:void getscore()void printstu(); 7.17.1 类和对象的定义类和对象的定义2022-2-22

4、北京邮电大学信息与通信工程学院-8-1 1、使用、使用类对象类对象如果已经知道某个类的功能和接口函数,就可以使用如果已经知道某个类的功能和接口函数,就可以使用它了。先定义类对象,通过对象调用接口函数实现一它了。先定义类对象,通过对象调用接口函数实现一定的功能。定的功能。class Student stu01; /class也可以省略不写stu01.getscore();stu01.printstu(); 这个过程的本质是:根据对象所需要完成的任务,向这个过程的本质是:根据对象所需要完成的任务,向对象发送消息。对象收到消息后,调用接口中的相应对象发送消息。对象收到消息后,调用接口中的相应的函数,

5、完成它的功能。对象只需要知道的函数,完成它的功能。对象只需要知道“做什么做什么”,具体工作由成员函数来完成。具体工作由成员函数来完成。 2022-2-22北京邮电大学信息与通信工程学院-9-2 2、类的声明类的声明类的声明具体说明类的组成,声明类的语法形式为:class 类名称 public:公有成员protect:保护型成员private:私有成员;2022-2-22北京邮电大学信息与通信工程学院-10-其中,“成员”既可以是数据成员,也可以是成员函数的原型。数据成员的声明方式与一般变量相同。函数成员是描述类的对象可以进行的操作,一般在类中声明原型,在类声明的外面定义函数的具体实现。 关键字

6、public、protect、private说明类成员的访问控制属性。私有(private)成员只允许本类的成员函数来访问;公有(public)成员是类对外的接口,在类声明和类(函数)实现之后,类的对象可以访问公有成员。保护型(protected)成员的可访问性和私有成员的性质相似。 2 2、类的声明类的声明2022-2-22北京邮电大学信息与通信工程学院-11-关于访问控制属性,注意:在类声明中,三种访问控制属性,可以按任意次序出现,也可以不出现。public等关键字也可以多次出现,但是一个成员只能具有一种访问控制属性。如果不写访问控制属性关键字,默认的是private。在书写时通常习惯将公

7、有类型放在最前面,这样便于阅读,因为它们是外部访问时所要了解的。一般情况下,一个类的数据成员应该声明为私有成员,这样封装性较好。一个类应该有一些公有的函数成员,作为对外的接口,否则别的代码无法访问类 2 2、类的声明类的声明2022-2-22北京邮电大学信息与通信工程学院-12-类的成员函数描述的是类的行为或操作。函数的原型声明要在类的主体中,原型说明了函数的参数表和返回值类型。而函数的具体实现一般是写在类声明之外的。在类的外部定义成员函数的语法形式为:返回值类型 类名:成员函数名(参数表)函数体 3 3、类的成员函数类的成员函数2022-2-22北京邮电大学信息与通信工程学院-13-如果在类

8、的内部定义成员函数的具体实现,则该成员函数为内联成员函数。函数定义时没有任何的附加说明,所以称为隐式声明的内联成员。 3 3、类的成员函数类的成员函数2022-2-22北京邮电大学信息与通信工程学院-14-定义一个对象和定义一个一般变量相同。定义变量时要分配存储空间,同样,定义一个对象时要分配存储空间,一个对象所占的内存空间是类的数据成员所占的空间总和。类的成员函数存放在代码区,不占内存空间。类的成员是抽象的,对象的成员才是具体的。类的数据成员都不会有具体的属性值。只有对象的成员才会有具体的属性值。4 4、对象、对象2022-2-22北京邮电大学信息与通信工程学院-15-声明了类及其对象,在类

9、的外部(指类定义和成员函数的实现代码之外),就可以访问对象的公有成员(包括数据成员和函数成员)了。 在类的外部,只能通过对象访问类的公有成员;在类的成员函数内部,可以直接访问类的所有成员,这就实现了对访问范围的有效控制。 4 4、对象、对象2022-2-22北京邮电大学信息与通信工程学院-16-类作用域是指类定义和相应的成员函数定义的范围,通俗地称为类的内部。 C+认为一个类的全部成员都是一个整体的相关部分。一个类的所有成员位于这个类的作用域内,在该范围内,一个类的成员函数对本类的其它成员具有无限制的访问权。 5 5、类的作用域与可见性、类的作用域与可见性2022-2-22北京邮电大学信息与通

10、信工程学院-17-要声明一个时钟类,任何一个时钟都应该有时、分、秒的值,这就是时钟的属性特征;时钟的操作应该有设置时间、显示时间等。 6 6、时钟类举例、时钟类举例2022-2-22北京邮电大学信息与通信工程学院-18-/声明时钟类的头文件:声明时钟类的头文件:Clock.hClock.h#include #include using namespace std;using namespace std;class Clockclass Clock/类的声明类的声明public:public: void SetTime(int newH=0,int newM=0,int newS=0); voi

11、d SetTime(int newH=0,int newM=0,int newS=0); void ShowTime(); void ShowTime(); void ShowTime(int n); void ShowTime(int n); private:private: int Hour; int Hour; int Minute; int Minute; int Second; int Second; 6 6、时钟类举例、时钟类举例2022-2-22北京邮电大学信息与通信工程学院-19-/实现类成员函数的源文件:实现类成员函数的源文件:Clock.cppClock.cpp#inclu

12、de Clock.h#include Clock.hvoid Clock:SetTime(int newH,int newM,int newS)void Clock:SetTime(int newH,int newM,int newS)/SetTime()/SetTime()函数定义函数定义 Hour=newH; Hour=newH; Minute=newM; Minute=newM; Second=newS; Second=newS; void Clock:ShowTime()void Clock:ShowTime()/ShowTime()/ShowTime()函数定义函数定义 coutHo

13、ur:Minute:Secondendl; coutHour:Minute:Secondendl; void Clock:ShowTime(int n)void Clock:ShowTime(int n) /重载函数的定义重载函数的定义 coutHour coutHour点点MinuteMinute分分SecondSecond秒秒endl;公有成员;例如:Clock c; /在栈中分配Clock型存储空间Clock* pc1=new Clock;/在堆中分配Clock型存储空间Clock* pc2=&c; pc1-SetTime(12,5,0);2022-2-22北京邮电大学信息与通信

14、工程学院-24-1 1、对象、对象指针指针/使用对象指针和堆对象对例使用对象指针和堆对象对例7-17-1中的主函数进行修改中的主函数进行修改void main()void main() Clock Clock* * pmyclock=new Clock; pmyclock=new Clock; pmyclock-SetTime(12, 5, 0); pmyclock-SetTime(12, 5, 0); pmyclock-ShowTime(); pmyclock-ShowTime(); delete pmyclock; delete pmyclock; 2022-2-22北京邮电大学信息与通信

15、工程学院-25-2 2、 thisthis指针指针问:一个类中所有对象调用的成员函数都执行同一段代码。那么,成员函数又是怎么识别当前是那个对象在访问呢? 答:this指针指出了成员函数当前所操作的数据所属的对象。不同的对象调用成员函数时,this指针将指向不同的对象,也就可以访问不同对象的数据成员。 2022-2-22北京邮电大学信息与通信工程学院-26-3 3、对象数组、对象数组对象数组的元素是对象,不仅具有数据成员,而且还有函数成员,可以通过数组元素调用成员函数。 2022-2-22北京邮电大学信息与通信工程学院-27-3 3、对象数组、对象数组/例例7-3 7-3 使用对象数组使用对象数

16、组#include #include #include #include #include #include using namespace std;using namespace std;class studentclass student private: private: int id; int id; string name; string name; int age; int age; float score; float score; public: public: void set(int, char void set(int, char* *, int, float);, in

17、t, float); void printstu() void printstu() cout cout学号:学号:id id 姓名:姓名:setw(5)name;setw(5)name; cout cout 年龄:年龄:age age 成绩:成绩:scoreendl;scoreendl; ; /student; /student类声明结束类声明结束 2022-2-22北京邮电大学信息与通信工程学院-28-3 3、对象数组、对象数组void student:set(int i, charvoid student:set(int i, char* * c, int a, float s) c,

18、int a, float s) id = i; id = i; name=c; name=c; age = a; age = a; score = s; score = s; void main()void main() student stu5; student stu5;/对象数组对象数组 stu0.set(1,wang,18, 86);stu0.set(1,wang,18, 86);/设置数组中每个对象设置数组中每个对象 stu1.set(2,Li,18, 72);stu1.set(2,Li,18, 72); stu2.set(3,zhao,18, 80); stu2.set(3,zha

19、o,18, 80); stu3.set(4,guo,18, 85);stu3.set(4,guo,18, 85); stu4.set(5,meng,18, 75); stu4.set(5,meng,18, 75); for (int i=0; i5; i+) for (int i=0; i5; i+) stui.printstu(); stui.printstu();/显示每个对象显示每个对象 2022-2-22北京邮电大学信息与通信工程学院-29-4 4、对象用做函数的参数和返回值、对象用做函数的参数和返回值可以将对象作为参数传递给一个函数或从函数返回一个对象。 直接用对象作为参数,调用函数

20、时,进行值传递,实参的值要复制给形参,如果类的数据成员较多时,需要一一复制,这种参数传递方式效率不高,可以使用对象指针或对象引用方式来传递函数参数。 2022-2-22北京邮电大学信息与通信工程学院-30-4 4、对象用做函数的参数和返回值、对象用做函数的参数和返回值/例例7-47-4:使用对象传递函数参数:使用对象传递函数参数/Tdate.h/Tdate.h:TdateTdate类声明类声明#include #include using namespace std;using namespace std;class Tdateclass Tdatepublic:public: void Se

21、t(int,int,int); void Set(int,int,int); /成员函数声明成员函数声明 int IsLeapYear();int IsLeapYear(); void Print(); void Print();private:private: int month; int month; int day; int day; int year; int year;2022-2-22北京邮电大学信息与通信工程学院-31-4 4、对象用做函数的参数和返回值、对象用做函数的参数和返回值/例例7-47-4:使用对象传递函数参数:使用对象传递函数参数/Tdate.cpp/Tdate.cp

22、p:TdateTdate类成员函数实现类成员函数实现#include Tdate.h#include Tdate.hvoid Tdate:Set(int m,int d,int y)void Tdate:Set(int m,int d,int y) month=m; day=d; year=y; month=m; day=d; year=y; int Tdate:IsLeapYear()int Tdate:IsLeapYear() return (year%4=0&year%100!=0)|(year%400=0); return (year%4=0&year%100!=0)|

23、(year%400=0); void Tdate:Print()void Tdate:Print() cout month / day / year endl; cout month / day / year endl; 2022-2-22北京邮电大学信息与通信工程学院-32-4 4、对象用做函数的参数和返回值、对象用做函数的参数和返回值/例例7-47-4:使用对象传递函数参数:使用对象传递函数参数/例例7-47-4的应用程序:的应用程序:7-4.cpp7-4.cpp#include #include using namespace std;using namespace std;#inclu

24、de Tdate.h#include Tdate.hvoid someFunc(Tdate someday)/void someFunc(Tdate someday)/普通函数的参数是一个类对象普通函数的参数是一个类对象 someday.Print(); someday.Print(); if(someday.IsLeapYear() if(someday.IsLeapYear() cout leap yearn; cout leap yearn; else else cout not leap yearn; cout not leap yearn; void main()void main(

25、) Tdate s; Tdate s; s.Set(2,15,2003); s.Set(2,15,2003); someFunc(s); /someFunc(s); /对象作为函数参数对象作为函数参数 2022-2-22北京邮电大学信息与通信工程学院-33-4 4、对象用做函数的参数和返回值、对象用做函数的参数和返回值/例例7-57-5:使用对象指针传递函数参数:使用对象指针传递函数参数/例例7-57-5的应用程序:的应用程序:7-5.cpp7-5.cpp#include #include using namespace std;using namespace std;#include Tda

26、te.h#include Tdate.h/包含包含Tdate.hTdate.h头文件头文件void someFunc(Tdatevoid someFunc(Tdate* * pS) pS)/对象指针作为函数形参对象指针作为函数形参 pS-Print(); pS-Print(); /pS/pS是是s s对象的指针对象的指针 if(pS-IsLeapYear()if(pS-IsLeapYear() cout leap yearn; cout leap yearn; else else cout not leap yearn;cout not leap yearn; void main()void

27、main() Tdate s; Tdate s; s.Set(2,15,2003); s.Set(2,15,2003); someFunc(&s);/ someFunc(&s);/对象的地址作为实参对象的地址作为实参 2022-2-22北京邮电大学信息与通信工程学院-34-4 4、对象用做函数的参数和返回值、对象用做函数的参数和返回值/例例7-77-7:使用对象的引用作为函数的返回值:使用对象的引用作为函数的返回值#include #include using namespace std;using namespace std;class Rectangleclass Rect

28、angle private: private: float width,height; float width,height;public:public: void SetRectangle(float newW, float newH) void SetRectangle(float newW, float newH) width = newW; width = newW; height=newH;height=newH; float Area() float Area() return width return width* *height;height; ;2022-2-22北京邮电大学

29、信息与通信工程学院-35-4 4、对象用做函数的参数和返回值、对象用做函数的参数和返回值/例例7-77-7:使用对象的引用作为函数的返回值:使用对象的引用作为函数的返回值Rectangle &compare(Rectangle & r1,Rectangle & r2)Rectangle &compare(Rectangle & r1,Rectangle & r2) if (r1.Area() r2.Area() if (r1.Area() r2.Area() return r1; return r1; else else return r2; r

30、eturn r2; void main()void main() Rectangle rect1,rect2,rect3; Rectangle rect1,rect2,rect3; rect1.SetRectangle(12,21); rect1.SetRectangle(12,21); rect2.SetRectangle(21,14); rect2.SetRectangle(21,14); rect3.SetRectangle(21,12); rect3.SetRectangle(21,12); Rectangle & maxR = compare(rect3,compare(re

31、ct1,rect2); Rectangle & maxR = compare(rect3,compare(rect1,rect2); cout The larger rectangle has area: maxR.Area() endl; cout The larger rectangle has area: maxR.Area() endl; 7.37.3 构造函数构造函数2022-2-22北京邮电大学信息与通信工程学院-37-7.37.3 构造函数构造函数每个对象区别于其他对象的地方主要有两个,外在的区别就是对象的标识符,即对象的名称,而内在的区别就是对象自身的属性值,即数据成员

32、的值。在定义一个对象的时候要给它分配存储空间,也可以同时给它的数据成员赋初值,称为对象的初始化。C+程序中的对象初始化工作由一个特殊的成员函数来完成,就是构造函数。因为不同类型的对象的初始化工作是不一样的,因此构造函数从属于某个类的,即每个类都要定义它自己的构造函数,它是类的成员函数。 2022-2-22北京邮电大学信息与通信工程学院-38-定义构造函数的一般形式为:class 类名 public:类名(形参表);/构造函数的原型/类的其它成员;类名:类名(形参表)/构造函数的实现/函数体 7.37.3 构造函数构造函数2022-2-22北京邮电大学信息与通信工程学院-39-构造函数的特点是:

33、构造函数的函数名与类名相同;而且没有返回值。构造函数一定是公有函数。作为类的成员函数,构造函数可以直接访问类的所有数据成员。在类的内部定义的构造函数是内联函数。构造函数可以带默认形参值,也可以重载。 7.37.3 构造函数构造函数2022-2-22北京邮电大学信息与通信工程学院-40-在声明类是如果没有定义类的构造函数,编译系统就会在编译时自动生成一个默认形式的构造函数,默认构造函数是构造对象时不提供参数的构造函数。 除了无参数构造函数是默认构造函数外,带有全部默认参数值的构造函数也是默认构造函数。 7.37.3 构造函数构造函数2022-2-22北京邮电大学信息与通信工程学院-41-/例例7

34、-87-8:构造函数的重载:构造函数的重载#include #include using namespace std;using namespace std;class Tdateclass Tdate public: public: Tdate(); Tdate();/第一个构造函数第一个构造函数 Tdate(int d); Tdate(int d); /第二个构造函数第二个构造函数 Tdate(int m,int d); Tdate(int m,int d); /第三个构造函数第三个构造函数 Tdate(int m,int d,int y); Tdate(int m,int d,int y

35、); /第四个构造函数第四个构造函数 /其他公共成员其他公共成员 private:private: int month; int month; int day; int day; int year; int year;7.37.3 构造函数构造函数2022-2-22北京邮电大学信息与通信工程学院-42-/例例7-87-8:构造函数的重载:构造函数的重载Tdate:Tdate()Tdate:Tdate() month=4; day=15; year=1995; month=4; day=15; year=1995; cout month / day / year endl; cout month

36、 / day / year endl; Tdate:Tdate(int d)Tdate:Tdate(int d) month=4; day=d; year=1996; month=4; day=d; year=1996; cout month / day / year endl; cout month / day / year endl; Tdate:Tdate(int m,int d)Tdate:Tdate(int m,int d) month=m; day=d; year=1997; month=m; day=d; year=1997; cout month / day / year en

37、dl; cout month / day / year endl; Tdate:Tdate(int m,int d,int y)Tdate:Tdate(int m,int d,int y) month=m; day=d; year=y; month=m; day=d; year=y; cout month / day / year endl; cout month / day / year endl; 7.37.3 构造函数构造函数2022-2-22北京邮电大学信息与通信工程学院-43-/例例7-87-8:构造函数的重载:构造函数的重载void main()void main() Tdate

38、aday; Tdate aday;/开始用开始用4 4种方式构造种方式构造4 4个对象个对象 Tdate bday(10);Tdate bday(10); Tdate cday(2,12); Tdate cday(2,12); Tdate dday(1,2,1998); Tdate dday(1,2,1998); 7.37.3 构造函数构造函数2022-2-22北京邮电大学信息与通信工程学院-44-复制构造函数就是函数的形参是类的对象的引用的构造函数。 通过等于号复制对象时,系统会自动调用复制构造函数。 复制构造函数与原来的构造函数实现了函数的重载。 如果程序在类定义时没有显式定义复制构造函数

39、,系统也会自动生成一个默认的复制构造函数,把成员值一一复制。某些情况下必须显式地定义一个复制构造函数。例如,如果类的数据成员包括指针变量,类的构造函数用new运算符为这个指针动态申请空间。7.37.3 构造函数构造函数2022-2-22北京邮电大学信息与通信工程学院-45-以下三种情况系统会自动调用复制构造函数:当用类的一个对象去初始化该类的另一个对象时 如果函数的形参是类的对象,调用函数时,进行形参和实参结合时 如果函数的返回值是类的对象,函数执行完成返回调用者时 7.37.3 构造函数构造函数 7.47.4 析构函数析构函数2022-2-22北京邮电大学信息与通信工程学院-47-与构造函数

40、相反,当对象生存期结束时,需要调用析构函数,释放对象所占的内存空间。与构造函数一样,析构函数也是类的一个公有成员函数,它的名称是在类名前加“”构成,没有返回值,和构造函数不同的是析构函数不接受任何参数。析构函数是在对象生存期即将结束的时刻由系统自动调用的。如果程序员没有定义析构函数,系统将自动生成和调用一个默认析构函数。 类的析构函数不能重载。 7.47.4 析构函数析构函数2022-2-22北京邮电大学信息与通信工程学院-48-/例例7-107-10:用户必须自己定义析构函数的示例:用户必须自己定义析构函数的示例#include #include using namespace std;us

41、ing namespace std;class studentclass studentpublic:public: student(int, char student(int, char* *, int, float);, int, float); student(student&); student(student&); student(); student(); void printstu(); void printstu(); private: private: int id; int id; char char* * name; name; int age; int

42、age; float score; float score;7.47.4 析构函数析构函数2022-2-22北京邮电大学信息与通信工程学院-49-student:student(int i, charstudent:student(int i, char* * c, int a, float s) c, int a, float s) coutConstructing.endl; coutConstructing.endl; id = i; id = i; age = a; age = a; score = s;score = s; name = new charstrlen(c)+1; na

43、me = new charstrlen(c)+1; if (name != 0) if (name != 0) strcpy(name, c); strcpy(name, c); student:student(student& s)student:student(student& s)/复制构造函数复制构造函数 coutCopy Constructing.endl; coutCopy Constructing.endl; id=s.id; id=s.id;/一般成员简单复制一般成员简单复制 age=s.age;age=s.age; score=s.score; score=s

44、.score; name = new charstrlen()+1; name = new charstrlen()+1;/先申请堆空间先申请堆空间 if (name != 0) if (name != 0) strcpy(name, ); strcpy(name, );/复制字符串复制字符串 7.47.4 析构函数析构函数2022-2-22北京邮电大学信息与通信工程学院-50-/例例7-107-10:用户必须自己定义析构函数的示例:用户必须自己定义析构函数的示例student:student()student:student() coutDes

45、tructing.endl; coutDestructing.endl; delete name; delete name; name=0; name=0; void student:printstu()void student:printstu() cout cout学号:学号:id id 姓名:姓名:name;name; cout cout 年龄:年龄:age age 成绩:成绩:scoreendl;scoreendl; void main()void main() student stu(1,wang,18, 86); student stu(1,wang,18, 86); stu.pr

46、intstu(); stu.printstu(); 7.47.4 析构函数析构函数 7.57.5 类的静态成员类的静态成员2022-2-22北京邮电大学信息与通信工程学院-52-1 1、静态数据成员静态数据成员静态数据成员是类的数据成员的一种特例,采用static关键字来声明。类的数据成员在类的每一个对象中分别存储不同的数值,但是静态数据成员则不同,它在整个类中只有一个拷贝,由该类的所有对象共同维护和使用,从而实现了同一类的不同对象之间的数据共享。2022-2-22北京邮电大学信息与通信工程学院-53-1 1、静态数据成员静态数据成员静态数据成员具有静态生存期。在类的声明中只能声明静态数据成员

47、的存在。由于类的声明是抽象的,静态数据成员的初始化需要在类的外部进行,通过类名对它进行访问。 2022-2-22北京邮电大学信息与通信工程学院-54-2 2、静态成员函数、静态成员函数可以通过定义和使用静态成员函数来访问静态数据成员。所谓静态成员函数就是使用static关键字声明函数成员。同静态数据成员一样,静态成员函数也属整个类,由同一个类的所有对象共同维护,为这些对象所共享。2022-2-22北京邮电大学信息与通信工程学院-55-2 2、静态成员函数、静态成员函数静态成员函数作为成员函数,它的访问属性可以受到类的严格控制。对公有静态成员函数,可以通过类名或对象名来调用;而一般的非静态公有成

48、员函数只能通过对象名来调用。静态成员函数可以直接访问该类的静态数据成员和函数成员;而访问非静态数据成员,必须通过参数传递方式得到对象名,然后通过对象名来访问。 2022-2-22北京邮电大学信息与通信工程学院-56-/例例7-117-11:静态数据成员的定义和使用:静态数据成员的定义和使用#include #include #include #include using namespace std;using namespace std;class Studentclass Studentpublic:public: Student(char Student(char* * pName =no

49、 name); pName =no name); Student(); Student(); static void PrintC() static void PrintC() coutThe number of students is countendl; coutThe number of students is countendl; private:private: static int count; static int count; /若写成若写成count=0count=0,则非法,则非法 string name;string name;7.57.5 类的静态成员类的静态成员202

50、2-2-22北京邮电大学信息与通信工程学院-57-Student:Student(charStudent:Student(char* * pName)/ =no name) pName)/ =no name) cout create one studentn; cout create one studentn; name=pName; name=pName; count+; / count+; /静态成员:每创建一个对象,学生人数增静态成员:每创建一个对象,学生人数增1 1 Student:Student()Student:Student() cout destruct one student

51、n; cout destruct one studentn; count-; / count-; /每析构一个对象,学生人数减每析构一个对象,学生人数减1 1 coutThe number of students is countendl; coutThe number of students is countendl; int Student:count =0; /int Student:count =0; /静态数据成员在类外分配空间和初始化,静态数据成员在类外分配空间和初始化,staticstatic不用写不用写void main()void main() Student:PrintC(

52、); Student:PrintC();/通过类名调用静态成员函数通过类名调用静态成员函数 Student s1;Student s1; s1.PrintC(); s1.PrintC(); Student s2; Student s2; s2.PrintC(); s2.PrintC(); 7.57.5 类的静态成员类的静态成员 7.67.6 类成员的保护和使用类成员的保护和使用2022-2-22北京邮电大学信息与通信工程学院-59-1 1、类的封装类的封装在程序设计中,将数据与操作数据的行为进行有机地结合,这就是封装。C+语言提供类这种语言成分来实现封装,类是属性和操作的结合体,并且在定义类的

53、属性和操作时,规定了它们的可见性。通过封装将一部分成员作为类与外部的接口,而将其它的成员隐藏起来,以防外界的干扰和误操作,使程序的不同模块之间的相互影响减小到最低限度。 2022-2-22北京邮电大学信息与通信工程学院-60-2 2、友元、友元在一个类中,可以利用关键字friend将别的模块(一般函数、其它类的成员函数或其它类)声明为本类的友元,这样类中本来隐藏的信息(私有和保护成员)就可以被友元访问。 友元提供了不同类或对象的成员函数之间、类的成员函数与一般函数之间进行数据共享的机制。 友元并不是类的成员。2022-2-22北京邮电大学信息与通信工程学院-61-2 2、友元、友元关于友元类,

54、要注意:友元关系是不能传递的。B类是A类的友元,C类是B类的友元,C类和A类之间,如果没有声明,就没有任何友元关系,不能进行数据共享。友元关系是单向的。如果声明B类是A类的友元,B类的成员函数就可以访问A类的私有和保护数据,但A类的成员函数却不能访问B类的私有和保护数据。 2022-2-22北京邮电大学信息与通信工程学院-62-/例例7-127-12:使用友元函数计算两点距离:使用友元函数计算两点距离#include #include #include #include using namespace std;using namespace std;class Pointclass Point

55、/Point/Point类定义类定义public:public:/外部接口外部接口 Point(int xx=0, int yy=0) X=xx;Y=yy;Point(int xx=0, int yy=0) X=xx;Y=yy; int GetX() return X; int GetX() return X; int GetY() return Y; int GetY() return Y; friend float fDist(Point &a, Point &b);/ friend float fDist(Point &a, Point &b);/友元函数

56、声明友元函数声明private:private:/私有数据成员私有数据成员 int X,Y;int X,Y;7.67.6 类成员的保护和使用类成员的保护和使用2022-2-22北京邮电大学信息与通信工程学院-63-/例例7-127-12:使用友元函数计算两点距离:使用友元函数计算两点距离float fDist(Point &p1, Point &p2)float fDist(Point &p1, Point &p2)/友元函数实现友元函数实现 double x=double(p1.X-p2.X);/ double x=double(p1.X-p2.X);/通过对

57、象访问私有数据成员通过对象访问私有数据成员 double y=double(p1.Y-p2.Y);double y=double(p1.Y-p2.Y); return float(sqrt(x return float(sqrt(x* *x+yx+y* *y);y); void main()void main()/主函数主函数 Point myp1(1,1),myp2(4,5); Point myp1(1,1),myp2(4,5);/定义定义PointPoint类的对象类的对象 coutThe distance is:;coutThe distance is:; coutfDist(myp1,

58、myp2)endl; coutfDist(myp1,myp2)endl; /计算两点间的距离计算两点间的距离 7.67.6 类成员的保护和使用类成员的保护和使用2022-2-22北京邮电大学信息与通信工程学院-64-/例例7-137-13:友元类的使用:友元类的使用#include #include using namespace std;using namespace std;class Student;class Student;/前向引用声明,只声明类名,类定义在后面前向引用声明,只声明类名,类定义在后面class Teacherclass Teacherpublic:public: T

59、eacher(int i, char Teacher(int i, char* * c); c); void show(); void show(); void assignGrades(Student& s); void assignGrades(Student& s);/使用未定义的类,需要前向引用声明使用未定义的类,需要前向引用声明private:private: char char* * name; name; int id; int id;class Studentclass Studentpublic:public: Student(int i, char Stud

60、ent(int i, char* * c, float s, Teacher c, float s, Teacher* * t); t); void printstu(); void printstu(); friend class Teacher; friend class Teacher;private:private: Teacher Teacher* * pT; pT; int sid; int sid; char char* * name; name; float grade; float grade;7.67.6 类成员的保护和使用类成员的保护和使用2022-2-22北京邮电大学信息与通信工程学院-65-Student:Student(int i, charStudent:Student(int i, char* * c, float s, Teacher c, float s, Teacher* *

温馨提示

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

评论

0/150

提交评论