
第15章静态成员函数与友元
第15章 静态成员函数与友元

目录静态成员的重要性15.1静态成员的使用15.2静态数据成员15.3静态成员函数15.415.5需要友元的原因友元的使用15.6
15.1 静态成员的重要性 15.2 静态成员的使用 15.3 静态数据成员 15.4 静态成员函数 15.5 需要友元的原因 15.6 友元的使用

15静态成员函数和友元类是类型而不是数据对象每个类的对象都是该类数据成员的拷贝然而,往往需要让类的所有对象在类的范围内共享某个数据。,声明为static的类成员便能在类范围中共享,称之为静态成员。友元函数完全是普通的C++函数,不同的是,它可以访问类的保护或私有成员,方便编程,提高了效率,但却破坏了类的封装
• 类是类型而不是数据对象。 • 每个类的对象都是该类数据成员的拷贝。 • 然而,往往需要让类的所有对象在类的范围内共 享某个数据。 • 声明为static的类成员便能在类范围中共享,称 之为静态成员。 • 友元函数完全是普通的C++函数。 • 不同的是,它可以访问类的保护或私有成员,方 便编程,提高了效率,但却破坏了类的封装

15.1静态成员的重要性要想得到现有的学生数,不能到类Student中去取。因为类不是一个占有内存的实体那么,到哪个对象中去取学生数?一且学生人数变化,需要每个对象都去修改吗?如果放到全局变量中,那么在类外面,不安全,也影响了封装性
• 要想得到现有的学生数,不能到类Student中 去取。 • 因为类不是一个占有内存的实体。 • 那么,到哪个对象中去取学生数? • 一旦学生人数变化,需要每个对象都去修改 吗? • 如果放到全局变量中,那么在类外面,不安 全,也影响了封装性

15.1静态成员的重要性例如:用全局变量来表示学生类链首指针和学生数classStudent(S链表首指针Student * pFirst ;int//学生人数count ;voidfn(){/创建第1个学生对象Student ss;/学生人数增1count++ ;//没有对pFirst约束,随便乱用,一点也不把它当链首指针pFirst = &ss;l//fn()退出时,ss作用域终止,ss被析构,可学生人数忘了减1
例如:用全局变量来表示学生类链首指针和学生数 class Student { //. } ; Student * pFirst ; //链表首指针 int count ; //学生人数 void fn( ) { Student ss ; //创建第1个学生对象 count++ ; //学生人数增1 //没有对pFirst约束,随便乱用,一点也不把它当链首指针 pFirst = &ss ; } //fn()退出时,ss作用域终止,ss被析构,可学生人数忘了减1

15.1青静态成员的重要性ch12-10.cpp:定义学号美和学生美#imclude -iostream:#i mcl ude -- cstring?usingnamespace stdint nextstudentid= :class studenticprivate:int value:全局变量nextStudentID即不能放在头文件中定义,也不能放在类StudentID中定义只能放在应用程序主函数main()的前面
• 全局变量nextStudentID即不能放在头文件中定 义,也不能放在类StudentID中定义。 • 只能放在应用程序主函数main( )的前面

15.1静态成员的重要性,若能将学生人数和链表首指针封装在类单面既可以受到类的保护,也可以作为一个类来重用。这是属于类的一部分,但并不适合用普通成员表示。也不适合用全局数据变量来表示·此时,可以用静态成员来表示
• 若能将学生人数和链表首指针封装在类里面, • 既可以受到类的保护,也可以作为一个类来 重用。 • 这是属于类的一部分,但并不适合用普通成 员表示。 • 也不适合用全局数据变量来表示。 • 此时,可以用静态成员来表示

15.2静态成员的使用类的成员有数据成员和成员函数之分。静态成员也有静态数据成员和静态成员函数之分。静态成员用static声明。类的构造函数和析构函数可以对静态数据成员进行操作,在应用程序中,也可以调用静态成员函数
• 类的成员有数据成员和成员函数之分。 • 静态成员也有静态数据成员和静态成员函数 之分。 • 静态成员用static声明。 • 类的构造函数和析构函数可以对静态数据成 员进行操作。 • 在应用程序中,也可以调用静态成员函数

15.2静态成员的使用ch15_1.cpp例如:类中定义静态数据成员和静态成员函数#include#includenoofStudent既不是using namespace std;对象s1,也不是对象classStudent(s2的一部分。staticint noofStudentsychar name[40] ;public:Student(char * pName ="no name")(cout<<"createonestudentn"strncpy(name,pName,40)name[39]="[0′;1静态成员:创建对象伴随学生人数增1noofStudents++;cout<<noOfstudents<<endl;;1
例如:类中定义静态数据成员和静态成员函数 #include #include using namespace std; class Student { static int noOfStudents ; char name[40] ; public: Student(char * pName = "no name" ) { cout<<"create one student\n"; strncpy(name, pName,40); name[39]='\0’; noOfStudents++; //静态成员:创建对象伴随学生人数增1 cout<<noOfStudents<<endl;; } noOfStudent既不是 对象s1,也不是对象 s2的一部分

运行结果:~Student( )create one student11cout<<"destructonestudentln"create one student//析构对象伴随人数减1noOfStudents--2cout<<noOfStudents<<endl ;21destruct one studentstaticint number()//静态成员函数1destruct one studentreturn noOfStudents ;001:int Student :: noOfStudents = O;/静态数据成员初始化void fn( )no0fStudent既不是对象s1,{也不是对象s2的一部分。Student s1;Student s2;cout<<Student::number(<<endl;//调用静态成员函数用类名1void main( )[fn ();cout<<Student:number()<<endl;//调用静态成员函数用类名1
~Student( ) { cout<<"destruct one student\n“ ; noOfStudents-; //析构对象伴随人数减1 cout<<noOfStudents<<endl ; } static int number ( ) //静态成员函数 { return noOfStudents ; } } ; int Student :: noOfStudents = 0; //静态数据成员初始化 void fn( ) { Student s1 ; Student s2 ; cout<<Student::number()<<endl ; //调用静态成员函数用类名 } void main( ) { fn ( ); cout<<Student::number( )<<endl ; //调用静态成员函数用类名 } 运行结果: create one student 1 create one student 2 2 destruct one student 1 destruct one student 0 0 noOfStudent既不是对象s1, 也不是对象s2的一部分