《挑战30天C++入门极限》C++类静态数据成员与类静态成员函数

 
 

C++类静态数据成员与类静态成员函数

  在没有讲述本章内容之前如果我们想要在一个范围内共享某一个数据,那么我们会设立全局对象,但面向对象的程序是由对象构成的,我们如何才能在类范围内共享数据呢?

  这个问题便是本章的重点:

  声明为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的状态并不会随着一个新的对象的新建而重新定义,尽而我们了解到静态成员函数由于与对象无关系,所以在其中是不能对类的普通成员进行直接操作的

  如果上面的 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(); 
}

  从上面的代码来看,原来单纯结构化编程需要的一个链表进入全局指针在这里被类的静态成员指针所替代(类的静态成员完全可以替代全局变量),这个例子的理解重点主要是要注意观察类成员的析构顺序,通过对析构顺序的理解,使用析构函数来进行节点的脱链操作。

 

 
 
posted @ 2019-07-15 10:06  landv  阅读(201)  评论(0编辑  收藏  举报