from:://http://blog.csdn.net/taina2008/article/details/1684834

把类中的函数都定义成静态函数,这样相当于在编译时就分配了空间,这样不需要实体对象也可以调用泪中的函数了。

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的状态并不会随着一个新的对象的新建而重新定义,尽而我们了解到类的静态成员是属于类的而不是属于哪一个对象的,所以静态成员的使用应该是类名称加域区分符加成员名称的,在上面的代码中就是Internet::count,虽然我们仍然可以使用对象名加点操作符号加成员名称的方式使用,但是不推荐的,静态态类成员的特性就是属于类而不专属于某一个对象。

静态成员函数的特性类似于静态成员的使用,同样与对象无关,调用方法为类名称加域区分符加成员函数名称,在上面的代码中就是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();  
}

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

C++类静态数据成员与类静态成员函数的更多相关文章

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

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

  2. 如何导出标准模板库(STL)类的实例化和包含STL类对象数据成员的类

    本文翻译自 https://support.microsoft.com/zh-cn/help/168958/how-to-export-an-instantiation-of-a-standard-t ...

  3. C++中static修饰的静态成员函数、静态数据成员

    1.静态成员函数.静态数据成员 在类中,用static修饰的成员函数被称为静态成员函数,而用static修饰的数据成员就称为静态数据成员:与普通的成员函数和数据成员不同, 静态成员函数和静态数据成员有 ...

  4. C++学习5-面向对象编程基础(构造函数、转换构造、静态数据成员、静态成员函数、友元)

    知识点学习 类 const作用 C语言的const限定符的含义为"一个不能改变值的变量",C++的const限定符的含义为"一个有类型描述的常量": const ...

  5. C++ 静态数据成员和静态成员函数

    一 静态数据成员: 1.静态数据成员的定义. 静态数据成员实际上是类域中的全局变量.所以,静态数据成员的定义(初始化)不应该被放在头文件中,因为这样做会引起重复定义这样的错误.即使加上#ifndef ...

  6. C++基础(静态数据成员和静态成员函数)

    [简介] 1.静态数据成员在类中声明,在源文件中定义并初始化: 2.静态成员函数没有this指针,只能访问静态数据成员: 3.调用静态成员函数:(1)对象.(2)直接调用: 4.静态成员函数的地址可用 ...

  7. 转:C语言中的static变量和C++静态数据成员(static member)

    转自:C语言中的static变量和C++静态数据成员(static member) C语言中static的变量:1).static局部变量        a.静态局部变量在函数内定义,生存期为整个程序 ...

  8. C++类中的常数据成员和静态数据成员的区别

    刚开始学习C++的类和对象的部分,对类中的常数据成员和静态数据成员的概念和用法经常混淆,所以今天整理一下,顺便说一下,今天是我的生日,祝我生日快乐,呵呵. 常数据成员 常数据成员是指在类中定义的不能修 ...

  9. 一个类的实例化对象所占空间的大小(对象大小= vptr(可能不止一个) + 所有非静态数据成员大小 + Aligin字节大小(依赖于不同的编译器))

    注意不要说类的大小,是类的对象的大小. 首先,类的大小是什么?确切的说,类只是一个类型定义,它是没有大小可言的. 用sizeof运算符对一个类型名操作,得到的是具有该类型实体的大小. 如果 Class ...

随机推荐

  1. URL传递的参数是UTF-8编码,在打开的页面正常显示(GB2312)的方法

    URL传递的参数采用的是UTF-8编码,在打开的子页面中显示乱码, URL传递的地址形如:http://localhost/test.aspx?orgname=%E5%8B%**%**%**%**&a ...

  2. JS模块化编程(一):CommonJS,AMD/CMD

    前言 模块化是什么? 为什么采用模块化? 场景: 一个html,因不同的业务需求开发,会不断的引入js文件.另外,a.js和b.js中的变量或函数必须是全局的,才能暴露给使用方. <script ...

  3. 修改MySQL中的数据

    一:insert语句 1.介绍 在执行插入语句前,需要具有执行INSERT语句的INSERT权限. 2.准备环境 3.简单insert语句 4.插入多行 在这种形式中,每行的值列表用逗号分隔. 如果为 ...

  4. 017 jquery中对样式的操作

    1.样式操作 2.css-dom操作 3.程序 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ...

  5. React Native Android启动白屏的一种解决方案下

    实现思路 思路大流程: 1.APP启动的时候控制ReactActivity从而显示启动屏. 2.编写原生模块,提供一个关闭启动屏的公共接口. 3.在js的适当位置(一般是程序初始化工作完成后)调用上述 ...

  6. Bzoj4558:分类讨论 计算几何 组合数学

    国际惯例的题面: 这题让我爆肝啦......这种计数显然容斥,正好不含任何坏点的我们不会算,但是我们能算至少含零个坏点的,至少含一个坏点的,至少含两个坏点的......所以最终的答案就是(至少含零个坏 ...

  7. BZOJ.4571.[SCOI2016]美味(主席树 贪心)

    题目链接 要求 \(b\ xor\ (a_j+x)\) 最大,应让 \(a_j+x\) 的最高位尽可能与b相反.带个减法Trie树好像很难做?反正我不会. 从最高位开始,如果这位b是0/1,判断是否存 ...

  8. 牛客OI赛制测试赛3游记

    A - 数字权重 题目大意: 一个\(n\)位的数字.设第\(i\)位的数为\(a_i\),其中\(a_1\)为最高位,\(a_n\)为最低位,\(k\)为给定的数字.求同时满足满足以下两个条件的数的 ...

  9. [Java]Spring框架

    在这里学习Spring框架: >>spring&struts框架学习 >>spring >>Java回顾之Spring基础 >>IBM Java ...

  10. GIT(7)----强制用远程代码覆盖本地修改

    清除本地修改 git reset --hard 拉代码 git pull Git Pull While Ignoring Local Changes? git pull 并强制覆盖本地修改