C++类静态数据成员与类静态成员函数
副标题#e#
在没有报告本章内容之前假如我们想要在一个范畴内共享某一个数据,那么我们会设立全局工具,但面向工具的措施是由工具组成的,我们如何才气在类范畴内共享数据呢?
这个问题即是本章的重点:
声明为static的类成员可能成员函数便能在类的范畴内配合享,我们把这样的成员称做静态成员和静态成员函数。
下面我们用几个实例来说明这个问题,类的成员需要掩护,凡是环境下为了不违背类的封装特性,我们是把类成员配置为protected(掩护状态)的,可是我们为了简化代码,使要说明的问题更为直观,更容易领略,我们在此处都配置为public。
以下措施我们来做一个模仿会见的例子,在措施中,每成立一个工具我们配置的类静态成员变自动加一,代码如下:
#include <iostream>
using namespace std;
class Internet
{
public:
Internet(char *name,char *address)
{
strcpy(Internet::name,name);
strcpy(Internet::address,address);
count++;
}
static void Internet::Sc()//静态成员函数
{
cout<<count<<endl;
}
Internet &Rq();
public:
char name[20];
char address[20];
static int count;//这里假如写成static int count=0;就是错误的
};
Internet& Internet::Rq()//返回引用的成员函数
{
return *this;
}
int Internet::count = 0;//静态成员的初始化
void vist()
{
Internet a1("中国软件开拓尝试室","www.cndev-lab.com");
Internet a2("中国软件开拓尝试室","www.cndev-lab.com");
}
void fn(Internet &s)
{
cout<<s.Rq().count;
}
void main()
{
cout<<Internet::count<<endl;//静态成员值的输出
vist();
Internet::Sc();//静态成员函数的挪用
Internet b("中国软件开拓尝试室","www.cndev-lab.com");
Internet::Sc();
fn(b);
cin.get();
}
上面代码我们用了几种常用的方法成立工具,当成立新工具并挪用其结构函数的时候,静态成员cout便运行加1操纵,静态成员的初始化应该在主函数挪用之前,而且不能在类的声明中呈现,通过运行进程的调查我们发明,静态成员count的状态并不会跟着一个新的工具的新建而从头界说,尽而我们相识到类的静态成员是属于类的而不是属于哪一个工具的,所以静态成员的利用应该是类名称加域区分符加成员名称的,在上面的代码中就是Internet::count,固然我们仍然可以利用工具名加点操纵标记加成员名称的方法利用,可是不推荐的,静态态类成员的特性就是属于类而不专属于某一个工具。
#p#副标题#e#
静态成员函数的特性雷同于静态成员的利用,同样与工具无关,挪用要领为类名称加域区分符加成员函数名称,在上面的代码中就是Internet::Sc();,静态成员函数由于与工具无干系,所以在个中是不能对类的普通成员举办直接操纵的。
假如上面的 static void Internet::Sc()修改成为:
static void Internet::Sc()//静态成员函数
{
cout<<name<<endl;//错误
cout<<count<<endl;
}
静态成员函数与普通成员函数的不同就在于缺少this指针,没有这个this指针自然也就无从知道name是哪一个工具的成员了。
按照类静态成员的特性我们可以简朴归纳出几点,静态成员的利用范畴:
1.用来生存工具的个数。
2.作为一个标志,标志一些行动是否产生,好比:文件的打开状态,打印机的利用状态,等等。
3.存储链表的第一个可能最后一个成员的内存地点。
为了做一些须要的操练,深入的把握静态工具的存在的意义,我们以前面的布局体的教程为基本,用类的方法描写一个线性链表,用于存储若干学生的姓名,代码如下:
#include <iostream>
using namespace std;
class Student
{
public:
Student (char *name);
~Student();
public:
char name[30];
Student *next;
static Student *point;
};
Student::Student (char *name)
{
strcpy(Student::name,name);
this->next=point;
point=this;
}
Student::~Student ()//析构进程就是节点的离开进程
{
cout<<"析构:"<<name<<endl;
if(point==this)
{
point=this->next;
cin.get();
return;
}
for(Student *ps=point;ps;ps=ps->next)
{
if(ps->next==this)
{
cout<<ps->next<<"|"<<this->next<<endl;
ps->next=next;//=next也可以写成this->next;
cin.get();
return;
}
}
cin.get();
}
Student* Student::point=NULL;
void main()
{
Student *c = new Student("marry");
Student a("colin");
Student b("jamesji");
delete c;
Student *fp=Student::point;
while(fp!=NULL)
{
cout<<fp->name<<endl;
fp=fp->next;
}
cin.get();
}
#p#分页标题#e#
从上面的代码来看,本来纯真布局化编程需要的一个链表进入全局指针在这里被类的静态成员指针所替代(类的静态成员完全可以替代全局变量),这个例子的领略重点主要是要留意调查类成员的析构顺序,通过对析构顺序的领略,利用析构函数来举办节点的脱链操纵。