本文要点:

1.static成员它不像普通的数据成员,static数据成员独立于该类的任意对象而存在,每个static数据成员是与类关联的对象,并不与该类的对象相关联!

aka:每个static数据成员可以看成是类的一个对象,而不与该类定义的对象有任何关系!

2.static数据成员是存储在程序的静态存储区,而并不是在栈空间上

3.不能对static数据成员在类内部进行初始化,要初始化的话必须在类外进行定义。如果类中有多个static数据成员,static数据成员初始化的次序是按照static数据成员在类中的声明次序进行初始化的,初始化了之后,就可以使用static数据成员了,我们可以通过作用域操作符从类直接调用static数据成员,或者通过对象,引用,或指向该类类型对象的指针间接调用(这种情况下static数据成员必须是public的访问权限,如果定义在private访问权限下是不行的)。const int 型的static成员便可以在类定义体内部进行初始化。记住一定只能是const int型的,换成const string ,double都不行的。

4.static数据成员的类型可以是该成员所属的类类型,非static数据成员被限定为其自生类对象的指针或引用

5.static成员是类的组成部分并不是任何对象的组成部分,因此,static成员函数没有this指针。我们知道,一般而言,类中的成员函数具有一个附加的隐含实参,即指向该类对象的一个指针。这个隐含实参命名为this。因为static成员函数不是任何对象的组成部分,所以static成员函数就没有this形参了。由于成员函数声明为const说明该成员函数不会修改该成员函数所属的对象,所以static成员函数不能声明为const。为什么呢?因为static成员函数不是任何对象的组成部分。static成员函数可以直接访问所属类的static成员,但是不能直接使用非static成员函数!也不能访问static const 类型的成员!

6.私有的静态成员只能通过类的静态成员函数进行修改 ,公有的静态成员可以直接进行修改,访问方式可以obj.j或者Test::j  

本文转载,在此感谢。

http://www.cnblogs.com/gysm/archive/2011/09/16/2179277.html

http://blog.csdn.net/naturebe/article/details/7554589

C++类中谈到static,我们可以在类中定义static成员,static成员函数!C++primer里面讲过:static成员它不像普通的数据成员,static数据成员独立于该类的任意对象而存在,每个static数据成员是与类关联的对象,并不与该类的对象相关联!这句话可能比较拗口,其实可以这么理解:每个static数据成员可以看成是类的一个对象,而不与该类定义的对象有任何关系!下面我们就来具体看看类中的static数据成员!

谈到数据成员,我们最先想到的应该是怎么去定义一个static数据成员,static数据成员是存储在程序的静态存储区,而并不是在栈空间上。既然是static数据成员,所以关键字static是必不可少的,例如:

 1 static.h文件 2 #include  <iostream> 3 #include  <string> 4 using namespace std; 5 class Person 6 { 7 private: 8     string name; 9     static int age;10 public:11     Person(const string&nm):name(nm)12     {}13     void Print()14     {15         cout<<name<<" is "<<age<<endl;16     }17 };18 int Person::age=20;19 20 static.cpp文件21 22 #include "stdafx.h"23 #include "static.h"24 #include <iostream>25 using namespace std;26 27 int _tmain(int argc, _TCHAR* argv[])28 {    29     Person person("tom");30     person.Print();31     cout<<endl;32     return 0;33 }

Person类中定义了一个static数据成员age,注意在类中不能对static数据成员在类内部进行初始化,要初始化的话必须在类外进行定义!注意,static数据成员不是通过类构造函数进行初始化的!如上面的代码所示:在类外定义int Person::age=20;这里前面就不要再加static了。如果类中有多个static数据成员,static数据成员初始化的次序是按照static数据成员在类中的声明次序进行初始化的,初始化了之后,就可以使用static数据成员了,我们可以通过作用域操作符从类直接调用static数据成员,或者通过对象,引用,或指向该类类型对象的指针间接调用(这种情况下static数据成员必须是public的访问权限,如果定义在private访问权限下是不行的)。

说到static数据成员,有一种情况不得不提,那就是特殊的const static成员。如上面所述,类的static成员,[像普通数据成员一样?],不能在类的定义体中进行初始化。只能在类外进行初始化。const int 型的static成员便可以在类定义体内部进行初始化。记住一定只能是const int型的,换成const string ,double都不行的。看下面这段代码:

static.h头文件#include  <iostream>#include  <string>using namespace std;
class Person
{
private:
    string name;
    static const int age=20;
    static string address;
public:
    Person(const string&nm):name(nm)
    {}
    static string Address();//静态成员函数可以在类内部声明和定义,也可以在类外部定义。
    /*{
        return address;
    }*/
    void Print()
    {
        cout<<name<<" is "<<age ;
    }
};
string Person::address="Beijing";
string Person::Address(){
    return address;
}

static.cpp文件

#include "stdafx.h"#include "static.h"#include <iostream>using namespace std;

int _tmain(int argc, _TCHAR* argv[]){        Person person("tom");    person.Print();    cout<<" and live in "<<person.Address();    cout<<endl;    return 0;}

只有age才能在类定义体内进行初始化,address是不行的。这段代码不能在VC6.0上运行的,它不支持。在vs2008上可以运行。在C++Primer里面有一段注解:const static数据成员在类的定义体中进行了初始化后,还必须在类的定义体之外进行定义。其实这是可要可不要的。上面的代码就没有这段代码实现,其实加上去也是可以的,没有关系。还有一点,static数据成员的类型可以是该成员所属的类类型,非static数据成员被限定为其自生类对象的指针或引用。例如:类定义位如下的情况:

class Person{private:    string name;     static const int age=20;    static string address;    static Person person1;    Person *person2;    Person person3;public:    Person(const string&nm):name(nm)    {}    static string Address()    {        return address;    }    void Print()    {        cout<<name<<" is "<<age ;    }};

如果没有定义person3,则能够顺利通过编译,但是加上了person3就不能通过编译了!

说完了static成员后,我们再来看看static成员函数,static成员是类的组成部分并不是任何对象的组成部分,因此,static成员函数没有this指针。我们知道,一般而言,类中的成员函数具有一个附加的隐含实参,即指向该类对象的一个指针。这个隐含实参命名为this。因为static成员函数不是任何对象的组成部分,所以static成员函数就没有this形参了。由于成员函数声明为const说明该成员函数不会修改该成员函数所属的对象,所以static成员函数不能声明为const。为什么呢?因为static成员函数不是任何对象的组成部分。static成员函数可以直接访问所属类的static成员,但是不能直接使用非static成员函数!也不能访问static const 类型的成员!在上面的代码中static  string Address()函数中如果是return name或者是return age都不行! 好吧,就说这么些吧,如果哪里有不当之处,还请各位指正!

下面用一个简单的程序加以理解

  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4. class   Test
  5. {
  6. public:
  7. static int j;
  8. static void   init();//init定义为static 或非static都可以修改static成员i的值
  9. static int revise_i(int x);
  10. int  get_i();
  11. //由于没有this指针,static成员函数不能访问对象的非static成员,用static输出k是非法的
  12. private:
  13. static int i;
  14. int k;
  15. const static int r = 1; //只有const static 成员在类定义时初始化,不确切,看上篇说的
  16. //若将上面的i直接初始化,编译时报错
  17. };
  18. //外部定义时不能再标示static 
  19. int Test::i=0; //very important:外部定义(正好一次),之后i只能通过init修改
  20. int Test::j=5; //j为public,之后可以直接访问和修改
  21. void   Test::init()
  22. {
  23. i=10;
  24. }
  25. int   Test::get_i()
  26. {
  27. return   i;
  28. }
  29. int Test::revise_i(int x)
  30. {
  31. i = x;
  32. return i;
  33. }
  34. int   main()
  35. {
  36. Test   obj;
  37. cout << obj.get_i() << endl; //通过
  38. obj.init(); //私有的静态成员只能通过类的静态成员函数进行修改
  39. cout << obj.get_i() << endl;
  40. cout << Test::j << endl;
  41. obj.j = 15;  ////私有的静态成员只能通过类的静态成员函数进行修改 ,公有的静态成员可以直接进行修改,访问方式可以obj.j或者Test::j 
  42. Test::revise_i(555);
  43. cout << "after revise_i, i = " << obj.get_i() << endl;
  44. cout << Test::j << endl;
  45. system("pause");
  46. return   0;
  47. }

C++中的static数据成员与static成员函数的更多相关文章

  1. C++中static数据成员详解

        本文和大家分享的主要是c++中static数据成员的相关用法及源码示例,希望能帮助大家更好的学习C++. static(静态存储)数据成员 StaticTest.cpp : 定义控制台应用程序 ...

  2. C++类中的static数据成员,static成员函数

    C++类中谈到static,我们可以在类中定义static成员,static成员函数!C++primer里面讲过:static成员它不像普通的数据成员,static数据成员独立于该类的任意对象而存在, ...

  3. java中static特殊性和final(static成员直接被访问,this不能用在static方法中,static不可访问非static)

    java的static关键字 java中,static修饰的成员变量和成员方法叫静态变量和静态方法,不依赖类特定的实例,被类的所有实例共享. 静态变量或类变量 和 实例变量,区别是: 静态变量在内存中 ...

  4. 为什么static数据成员一定要在类外初始化?(转)

    1.避免重复定义和初始化 <<c++ primer>>说在类外定义和初始化是保证static成员变量只被定义一次的好方法. 但,为什么static const int就可以在类 ...

  5. static数据成员与const数据成员的定义与初始化

    三种数据类型的初始化 1.static int a 的初始化 const int a 的初始化 static const int a的初始化 三种初始化方式 在类外初始化 在构造函数中通过初始化列表初 ...

  6. c++学习(三)------static数据与成员函数

    疑惑: static类型成员是类的全局变量,所有类的实例都享有这个变量,或者说这个变量不属于任何一个类的实例. static类型变量可以为private,或public或其他(static数据可以被继 ...

  7. C++中类中常规变量、const、static、static const(const static)成员变量的声明和初始化

    C++类有几种类型的数据成员:普通类型.常量(const).静态(static).静态常量(static const).这里分别探讨以下他们在C++11之前和之后的初始化方式. c++11之前版本的初 ...

  8. vue-cli项目 build后请求本地static文件中的 json数据,路径不对,报错404处理方法

    vue-cli 项目 build  出错点: 1,build生成dist 放在tomcat上 报错,不显示内容  解决办法: config>index.js===>assetsPublic ...

  9. static类成员(变量和函数)

    0. 使用背景 对于特定类类型的全体对象而言,访问一个全局对象有时是必要的.也许,在程序的任意点需要统计已创建的特定类类型对象的数量:或者,全局对象可能是指向类的错误处理例程的一个指针:或者,它是指向 ...

随机推荐

  1. Linux强制访问控制机制模块分析之mls_type.h

    2.4.2 mls_type.h 2.4.2.1文件描述 对于mls_type.h文件,其完整文件名为security/selinux/ss/mls_types.h,该文件定义了MLS策略使用的类型. ...

  2. POJ1995(整数快速幂)

    http://poj.org/problem?id=1995 题意:求(A1^B1 + A2^B2 + .....Ah^Bh)%M 直接快速幂,以前对快速幂了解不深刻,今天重新学了一遍so easy ...

  3. c# 闭包 小例

    class Program { static void fnnn() { string[] k = new string[] { "x", "y", " ...

  4. centos 配置固定ip

    centos下网络配置方法(网关.dns.ip地址配置) 来源:互联网 作者:佚名 时间:07-13 00:32:07 [大 中 小] 本文介绍了centos网络配置的方法,centos网络配置主要包 ...

  5. WGS84、Web墨卡托、火星坐标、百度坐标互转

    转自:1.http://blog.csdn.net/wildboy2001/article/details/12031351 2.http://kongxz.com/2013/10/wgs-cgj/ ...

  6. 浏览器的中的 XMLHttpRequest 对象的使用

    使用XMLHttpRequest浏览器对象(IE5.IE6中是ActiveXObject对象)可以实现异步请求,Ajax就是以此为基础进行的封装. 1.同步与异步: <script type=& ...

  7. STL中算法

    sort 大数据量时,采用Quick Sort,分段递归排序: 小数据量时,采用Insert Sort. 如果迭代层次过深,会导致快排性能退化,这时采用Heap Sort排序. 快排pivot采用三点 ...

  8. Commando War

    Commando War“Waiting for orders we held in the wood, word from the front never cameBy evening the so ...

  9. HNU 12827 NASSA’s Robot

    题目链接:http://acm.hnu.cn/online/?action=problem&type=show&id=12827&courseid=268 #include&l ...

  10. 将Web应用性能提高十倍的10条建议

    导读 提高 web 应用的性能从来没有比现在更重要过.网络经济的比重一直在增长:全球经济超过 5% 的价值是在因特网上产生的(数据参见下面的资料).这个时刻在线的超连接世界意味着用户对其的期望值也处于 ...