本文要点:

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. Eclipse启动Tomcat错误:Several ports (8005,8009) required by Tomcat v6.0 Server at localhost are already

    解决办法: 1.netstat -aon|findstr 8005 可查看指定端口号使用情况 2.tasklist |findstr 10452 找出占用指定进程Id的程序 3.taskkill /p ...

  2. 【干货】Laravel --实战篇 UUID(唯一识别码)

    前言 : 一般的唯一识别id都是各种时间戳.毫秒级时间戳加php内置函数或者加上随机数等手段来生成的. 下面给大家介绍一个组件,也是我在各个实战项目中必不可少的一个组件,ramsey/uuid.一.r ...

  3. 常用数据库 JDBC URL 格式

    一 常用数据库 JDBC URL 格式 1 sqLite  驱动程序包名:sqlitejdbc-v056.jar 驱动程序类名: org.sqlite.JDBC JDBC URL: jdbc:sqli ...

  4. 基础总结篇之三:Activity的task相关

    http://blog.csdn.net/liuhe688/article/details/6761337 古人學問無遺力,少壯工夫老始成.紙上得來終覺淺,絕知此事要躬行.南宋.陸遊<冬夜讀書示 ...

  5. 怎样分析java线程堆栈日志

    注: 该文章的原文是由 Tae Jin Gu 编写,原文地址为 How to Analyze Java Thread Dumps 当有障碍,或者是一个基于 JAVA 的 WEB 应用运行的比预期慢的时 ...

  6. 浅谈php对api开发的作用

    最近正在做一个手机APP的服务端API开发,虽然是基于Ruby on Rails的,做的也不太专业,不过大致相通,希望能够给你一些启发. 首先,如果是比较简单的手机APP,例如新闻客户端这样的不会涉及 ...

  7. OOA/OOD/OOP(了解)

    Object-Oriented Analysis:面向对象分析方法 是在一个系统的开发过程中进行了系统业务调查以后,按照面向对象的思想来分析问题.OOA与结构化分析有较大的区别.OOA所强调的是在系统 ...

  8. --hdu 2124 Repair the Wall(贪心)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2124 Ac code : #include<stdio.h> #include<st ...

  9. 锋利的jQuery-3--css("height")和.height()的区别

    $("p").css("height") : 获取的高度值与样式的设置有关,可能会得到“auto”, 也可能是字符串“10px”之类的.设置值时如果是数值形式默 ...

  10. gdb命令与调试方法

    单线程 http://www.cnblogs.com/lidabo/p/5629830.html 编译程序一定要加-g选项 gcc -g test.c -o test 进入gdb调试:gdb 程序名 ...