类中的静态成员真是个让人爱恨交加的特性。我决定好好总结一下静态类成员的知识点,以便自己在以后面试中,在此类问题上不在被动。

静态类成员包括静态数据成员和静态函数成员两部分。 



一 静态数据成员: 



类体中的数据成员的声明前加上static关键字,该数据成员就成为了该类的静态数据成员。和其他数据成员一样,静态数据成员也遵守public/protected/private访问规则。同时,静态数据成员还具有以下特点:

1.静态数据成员的定义。 

静态数据成员实际上是类域中的全局变量。所以,静态数据成员的定义(初始化)不应该被放在头文件中。

其定义方式与全局变量相同。举例如下: 



xxx.h文件 

class base{ 

private: 

static const int
_i;//声明,标准c++支持有序类型在类体中初始化,但vc6不支持。

}; 



xxx.cpp文件 

const int
base::_i=10;//定义(初始化)时不受private和protected访问限制.

注:不要试图在头文件中定义(初始化)静态数据成员。在大多数的情况下,这样做会引起重复定义这样的错误。即使加上#ifndef
#define #endif或者#pragma
once也不行。 



2.静态数据成员被
类的所有对象所共享,包括该类派生类的对象。即派生类对象与基类对象共享基类的静态数据成员。举例如下:

class base{ 

public : 

static int _num;//声明 

}; 

int base::_num=0;//静态数据成员的真正定义 



class derived:public base{ 

}; 



main() 



base a; 

derived b; 

a._num++; 

cout<<"base class static data number
_num
is"<<a._num<<endl;

b._num++; 

cout<<"derived class static data
number _num
is"<<b._num<<endl;



// 结果为1,2;可见派生类与基类共用一个静态数据成员。 



3.静态数据成员可以成为成员函数的可选参数,而普通数据成员则不可以。举例如下:

class base{ 

public : 

static int _staticVar; 

int _var; 

void foo1(int
i=_staticVar);//正确,_staticVar为静态数据成员

void foo2(int
i=_var);//错误,_var为普通数据成员 

}; 



4.★静态数据成员的类型可以是所属类的类型,而普通数据成员则不可以。普通数据成员的只能声明为
所属类类型的指针或引用
。举例如下: 



class base{ 

public : 

static base
_object1;//正确,静态数据成员 

base _object2;//错误 

base *pObject;//正确,指针 

base
&mObject;//正确,引用

}; 



5.★这个特性,我不知道是属于标准c++中的特性,还是vc6自己的特性。

静态数据成员的值在const成员函数中可以被合法的改变。举例如下:

class base{ 

public: 

base(){_i=0;_val=0;} 



mutable int _i; 

static int _staticVal; 

int _val; 

void test() const{//const 成员函数 



_i++;//正确,mutable数据成员 

_staticVal++;//正确,static数据成员 

_val++;//错误 





}; 

int base::_staticVal=0; 



二,静态成员函数 

静态成员函数没有什么太多好讲的。 



1.静态成员函数的地址可用普通函数指针储存,而普通成员函数地址需要用
类成员函数指针来储存。举例如下: 

class base{ 

static int func1(); 

int func2(); 

}; 



int
(*pf1)()=&base::func1;//普通的函数指针

int
(base::*pf2)()=&base::func2;//成员函数指针

2.静态成员函数不可以调用类的非静态成员。因为静态成员函数不含this指针。

3.静态成员函数不可以同时声明为
virtual、const、volatile函数。举例如下: 

class base{ 

virtual static void
func1();//错误 

static void func2() const;//错误 

static void func3()
volatile;//错误 

}; 





最后要说的一点是,静态成员是可以独立访问的,也就是说,无须创建任何对象实例就可以访问,举例如下:

#include <iostream>

using namespace std;

class A

{

public:

 int m_a;

 static int m_count; // 注意属性为public

public:

 A(int
x):m_a(x){cout<<"A"<<endl;};

int getData()

 {

  return m_count;

 }

 int get_m_a_data() // 非静态成员函数可以访问静态成员变量

 {

  m_count +=1;

  return m_count;

 }

 static int get_m_count()

 {

  //m_a
+=1;    //
静态成员函数没有this指针,不能访问非静态成员变量

  //return m_a; // 同上

m_count +=1;

  return m_count;

  

 }

};

int A:: m_count=0; // 静态成员变量一定要初始化

int main()

{

 

 cout<<m_count<<endl; //
报错

 cout<<A::m_count<<endl;

return 0;

}

转自:http://www.cnblogs.com/lzjsky/archive/2011/01/24/1943199.html

C++ static成员变量与static成员函数的更多相关文章

  1. Java的初始化执行顺序(父类static变量->子类static变量->父类成员变量->父类构造器->成员变量->构造器->main函数)

    1. 引言 了解Java初始化的顺序,有助于理解Java的初始化机制和内存机制. 顺序:父类static变量->子类static变量->父类成员变量->父类构造器->成员变量- ...

  2. Java中变量之局部变量、本类成员变量、父类成员变量的访问方法

    变量:局部变量.本类成员变量.父类成员变量 如何访问:如果变量名相同,则采用就近原则,哪个变量离所要调用的访问最近,那就么就输出,优先顺序为:局部变量 > 本类成员变量 > 父类成员变量 ...

  3. static 成员变量、static 成员函数、类/对象的大小

    一.static 成员变量 对于特定类型的全体对象而言,有时候可能需要访问一个全局的变量.比如说统计某种类型对象已创建的数量. 如果我们用全局变量会破坏数据的封装,一般的用户代码都可以修改这个全局变量 ...

  4. static成员变量和static成员函数例程

    #include "pch.h" #include <iostream> using namespace std; class goods { public: good ...

  5. static 类成员变量 和 static const类成员变量

    1.使用static类的优点: (1)避免与其他类的成员或者全局变量冲突 (2)可以封装 (3)阅读性好 2.static 数据成员独立于该类的任意对象而存在 static数据成员的类型可以是该成员所 ...

  6. 牛客网Java刷题知识点之关键字static、static成员变量、static成员方法、static代码块和static内部类

    不多说,直接上干货! 牛客网Java刷题知识点之关键字static static代表着什么 在Java中并不存在全局变量的概念,但是我们可以通过static来实现一个“伪全局”的概念,在Java中st ...

  7. java类中的static成员变量和static方法简单介绍,持续补充

    一.静态成员变量 1.属于整个类而不是某个对象实例,所以可以直接通过类名和对象名去调用. 2.静态成员属于整个类,当系统第一次使用该类时,就会为其分配内存空间直到该类被卸载才会进行资源回收 二.静态方 ...

  8. java中对象多态时成员变量,普通成员函数及静态成员函数的调用情况

    /* 样例1: class Parent{ int num = 3; } class Child extends Parent{ int num = 4; } */ /* 样例2: class Par ...

  9. C++(三十二) — 常对象、常成员变量、常成员函数

    常量:对于既需要共享.又需要防止改变的数据.在程序运行期间不可改变. const 修饰的是对象中的 this 指针.所以不能被修改. 1.常对象 数据成员值在对象的整个生存期内不能改变.在定义时必须初 ...

随机推荐

  1. WIN7+IE8环境QTP11不能录制和识别web对象的解决方法

    在项目稍微空闲的时间,在办公电脑上面装上QTP11来学习.但是发现在录制脚本时无法录制web对象,在网上找解决方法说以管理员的身份运行QTP就可以解决无法录制的问题,用这方法证明是ok的.后来用Obj ...

  2. DateTable转化为泛型集合

    public class ListUtil { public static List<T> ToList<T>(DataTable dt) { List<T> li ...

  3. mock server 前后端分离小结(转)

    1.前台开发受限于后台开发的速度 2.后台提供给前台的接口缺字段,时常需要联调 基于Mock Server开发的好处: 对于前端来讲,可以独立于后端进行开发. 对于后端来讲,根据前端定义的接口进行开发 ...

  4. HTML的基本标签

    整理一下这一周学习的一些知识. 首先是一些基本标签. <!DOCTYPE HTML><html> 文档类型声明: 让浏览器,按照html5的标准对代码进行解释与执行.文档类型声 ...

  5. eclipse没有联想功能的解决办法

    1.我window->Preferences->Java->Editor->content assist 把 Enable auto activation 选项打上勾 :(如下 ...

  6. mac系统webstorm快捷键

    WebStorm 是jetbrains公司旗下一款JavaScript 开发工具.被广大中国JS开发者誉为"Web前端开发神器"."最强大的HTML5编辑器". ...

  7. sublime text3 3143 注册码

    sublime text3  3143 注册码,可用~ Sublime Text一款具有代码高亮.语法提示.自动完成且反应快速的编辑器软件,不仅具有华丽的界面,还支持插件扩展机制.相比于难于上手的Vi ...

  8. 封装bootstrap-treegrid组件

    封装bootstrap-treegrid组件   阅读目录 一.开源的treegrid 1.组件效果预览 2.组件开源地址 二.封装treegrid 1.组件封装的必要性 2.组件封装代码示例 3.封 ...

  9. 201521123082 《Java程序设计》第11周学习总结

    201521123082 <Java程序设计>第11周学习总结 标签(空格分隔):java 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. Answe ...

  10. 201521123056 《Java程序设计》第6周学习总结

    1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 注1:关键词与内容不求多,但概念之间的联系要清晰,内容覆盖 ...