1 / 28
文档名称:

静态成员和友元.ppt

格式:ppt   大小:1,408KB   页数:28页
下载后只包含 1 个 PPT 格式的文档,没有任何的图纸或源代码,查看文件列表

如果您已付费下载过本站文档,您可以点这里二次下载

分享

预览

静态成员和友元.ppt

上传人:文库新人 2021/10/25 文件大小:1.38 MB

下载得到文件列表

静态成员和友元.ppt

文档介绍

文档介绍:静态成员和友元
第一页,共28页
引入
考虑一个学生管理系统,有时候需要向系统添加一个学生,有时候需要从系统中删除一个学生。我们希望能够随时显示该系统中的所有学生,并且能够随时获取系统中的学生总数。
使用链表来存储所有的学生。
要求在一个常数时间内得到系统中的学生总数。
第二页,共28页
静态成员-背景
使用类数据成员保存链表头指针和学生总数的作法是不可取的,因为每个该类的对象都拥有一份副本,需要花费精力来维护这些副本的一致性(这些副本必须完全相同)。
设置全局变量来保存链表头指针和学生总数的作法可行,但是不够安全,因为程序的任何地方都可以修改这两个变量(导致程序的行为异常)。
【演示】
第三页,共28页
静态成员-引入
可以使用静态成员解决上述问题。
静态成员包括两种:
静态数据成员:使用关键字static修饰的数据成员。
静态成员函数:使用关键字static修饰的成员函数。
补充:C语言中使用static关键字描述了变量或者函数的可见性。
全局静态变量/对象是只在当前源文件中可见的全局变量或者对象。示例
不同源文件中可以定义同名的全局静态变量,但是各自占用的内存不同。
局部静态变量/对象是只在函数局部作用域内可见的变量或者对象,其生存期等于程序的生存期。
静态函数是只在当前源文件中可见的函数。不同源文件中可以定义同名的静态函数。示例
第四页,共28页
静态数据成员
使用static关键字修饰数据成员。
静态数据成员不属于该类的任何对象,而是由该类的所有对象共享。
静态数据成员是属于类的,而不是属于对象的。
一个类的静态数据成员只有一个,无论该类目前有多少个对象。
公有的静态数据成员可以在程序的任何地方访问,非公有的静态数据成员只能在类的作用域内或者友元中访问。
class Student
{

private:
char m_name[20];
Student* m_pNext;
Student* m_pPrev;
static Student* m_pListHead;
};
第五页,共28页
静态数据成员-访问
在类的成员函数中可以直接访问此类的静态数据成员,无需使用任何成员访问算符(.和->)。
在非成员函数中可以以两种方式访问一个类的公有静态数据成员。
通过该类的对象,->算符访问
使用类名限定的成员名来访问
Student::Student(char* name)
: m_pNext(NULL),
m_pPrev(NULL)
{

// 每构造一个对象,学生总
// 数应该加1
++s_nStudentCount;
}
Student s(“aa”);
Student t(“bb”);
cout << ; // OK
cout << ; // OK
cout << Student::s_nCount; //OK
// 以下断言成立
assert(&==&);
assert(&==&Student::s_nCount);
第六页,共28页
静态数据成员-唯一性
一个对象占用空间的大小和静态数据成员大小无关,换句话说:一个对象占用空间的大小是由该类所有非静态数据成员大小之和决定的。
默认的拷贝构造行为会拷贝静态成员吗?
静态数据成员所占用的空间不会随着对象的产生而分配,也不会随着对象的销毁而回收。静态数据成员具有静态生存期。
静态数据成员保存在程序的全局数据区中。
在main函数开始运行之前就已经准备好了。
在main函数返回之后结束其生存期。
第七页,共28页
class Student
{
public:
Student(char* name);
~Student();
private:
char m_name[20];
Student* m_pNext;
Student* m_pPrev;
static Student* s_pListHead;
};
void main()
{
Student* p1 = new Student(“a”);
Student* p2 = new Student(“b”);
Student* p3 = new Student(“c”);

}
Heap
“aaaa”
m_pNext
m_pPrev
“bbbb”
m_pNext
m_pPrev
“cccc”
m_pNext
m_pPrev
全局数据区
s_