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

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



一 静态数据成员: 



类体中的数据成员的声明前加上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. Jquery笔记之第二天

    Jquery笔记之第二天 jQuery - 获取内容和属性 获得内容 - text().html() 以及 val() <script> $(document).ready(functio ...

  2. MongoDB-python的API手记

    -------------------python调用MongoDB------------------- 1.官方文档:http://api.mongodb.org/python/current/t ...

  3. java.lang.reflect.MalformedParameterizedTypeException异常问题

    做dubbo框架集成的时候,出现的问题,本来的原来的工程没有错误,引入dubbo后报错,原因是spring的jar文件冲突,我用的spring是4.x,dubbo引入的是2.5所以需要去掉,相关的po ...

  4. element-ui更换主题色

    1.cd到你的项目文件目录下,npm i element-theme -g 2.npm i element-theme-default -D 3.et -i 执行后当前目录会有一个 element-v ...

  5. h5video标签

    在video标签中,我们可以使用属性:videoWidth & videoHeight,它获取的是video的宽度和高度(媒体本身).虽然不能直接使用,但是可以通过计算宽高比得到 video ...

  6. Promise的用法

    promise.then().promise.catch().Promise.all()... Promise 构造函数接受一个函数作为参数,该函数的2个参数分别是 resolve 和 reject. ...

  7. java 读写锁详解

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt124 在java多线程中,为了提高效率有些共享资源允许同时进行多个读的操作, ...

  8. java8 去掉 perm 用 Metaspace 来替代

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt266 正如大家所知,JDK 8 Early Access版已经提供下载.这使 ...

  9. Java基础学习 —— bat处理文件

    bat处理文件:就是一次性可以执行多个命令的文件 为什么要学bat处理文件? 快速运行一个软件我一般都会打包成jar包的形式来执行jar双击对图形界面管用 但是对控制台的程序是不起作用的.对于控制台的 ...

  10. Java中死锁的简单例子及其避免

    死锁:当一个线程永远地持有一个锁,并且其他线程都尝试获得这个锁时,那么它们将永远被阻塞.比如,线程1已经持有了A锁并想要获得B锁的同时,线程2持有B锁并尝试获取A锁,那么这两个线程将永远地等待下去. ...