Chinaunix首页 | 论坛 | 博客
  • 博客访问: 6455419
  • 博文数量: 2759
  • 博客积分: 1021
  • 博客等级: 中士
  • 技术积分: 4091
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-11 14:14
文章分类

全部博文(2759)

文章存档

2019年(1)

2017年(84)

2016年(196)

2015年(204)

2014年(636)

2013年(1176)

2012年(463)

分类: C/C++

2013-02-03 12:25:56

原文地址:C++ static用法总结 作者:iWonderLinux

低于类级

  1.与c语言里面的用法一致,用static标示的函数或者变量,不能被外部文件extern引用(即使编译不报错,链接时也会报错)

  2.static的第二个作用是保持变量内容的持久,存储在静态数据区的变量会在程序刚开始运行时就完成初始化。例子很多,类似全局变量。

类级

  3.类的静态普通成员变量

  静态成员变量一定要放在definition的地方,也就是cpp文件中定义。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class A
{
public:
    A(int t):a(t)
    {
    }
    int a;
};
 
class WithStatic {
   static int x;
   static A a;
public:
   void print() const {
     cout << "WithStatic::x = " << x << endl;
   }
};
1
2
3
4
5
6
7
8
9
int WithStatic::x = 1;
A   WithStatic::a(100);
  
 
int main()
{
   WithStatic ws;
   ws.print();
}


  4.类的静态数组或自定义成员变量


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
class X {
   int i;
public:
   X(int ii) : i(ii) {}
};
 
class Values {
  // static consts are initialized in-place:
  static const int scSize = 100;
   static const long scLong = 100;
   // Automatic counting works with static arrays.
   // Arrays, Non-integral and non-const statics
   // must be initialized externally:
   static const int scInts[];
   static const long scLongs[];
   static const float scTable[];
   static const char scLetters[];
   static int size;
   static const float scFloat ;
   static const float scFloat1 = 1.1;
  static const char scChar = 'b';
   static float table[];
   static char letters[];
    
   // This doesn't work, although
   // you might want it to:
//   static const X x(100) ;
   // Both const and non-const static class
   // objects must be initialized externally:
   static X x2;
   static X xTable2[];
   static const X x3;
   static const X xTable3[];
};
int Values::size = 100;
const float Values::scFloat = 1.1;
const int Values::scInts[] = {
   99, 47, 33, 11, 7
};
const long Values::scLongs[] = {
   99, 47, 33, 11, 7
};
const float Values::scTable[] = {
   1.1, 2.2, 3.3, 4.4
};
const char Values::scLetters[] = {
   'a', 'b', 'c', 'd', 'e',
   'f', 'g', 'h', 'i', 'j'
};
float Values::table[4] = {
   1.1, 2.2, 3.3, 4.4
};
char Values::letters[10] = {
   'a', 'b', 'c', 'd', 'e',
   'f', 'g', 'h', 'i', 'j'
};
X Values::x2(100);
X Values::xTable2[] = {
   X(1), X(2), X(3), X(4)
};
const X Values::x3(100);
const X Values::xTable3[] = {
   X(1), X(2), X(3), X(4)
};
int main() { Values v; }


 

虽然 之前说 static的必须要在类外定义,但是对于内建类型(built-in type)加了const后,可以在类中定义。

但是对于用户自定义类型和数组(哪怕是built-in type),必须在类外定义。



  5.类的静态函数

  静态成员函数只能访问静态成员变量和静态成员函数。因为没有this指针。

  非静态成员函数可以访问静态成员变量和静态成员函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class X
{
    int i;
    static int j;
    public:
    X(int ii = 0) : i(ii) {
        // Non-static member function can access
        // static member function or data:
        j = i;
    }
    int val() const {
        incr(); // OK
        return i; }
    static int incr() {
        //! i++; // Error: static member function
        // cannot access non-static member data
        return ++j;
    }
    static int f() {
        //! val(); // Error: static member function
        // cannot access non-static member function
        return incr(); // OK -- calls static
    }
};
int X::j = 0;
 
int main() {
    X x;
    X* xp = &x;
    x.f();
    xp->f();
    X::f(); // Only works with static members
}


  6.静态对象的构造函数和析构函数

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
using namespace std;
 
class Obj {
    char c; // Identifier
public:
    Obj(char cc) : c(cc) {
    cout << "Obj::Obj() for " << c << endl;
}
~Obj() {
    cout << "Obj::~Obj() for " << c << endl;
}
};
Obj a('a'); // Global (static storage)
// Constructor & destructor always called
void f() {
    static Obj b('b');
}
void g() {
    static Obj c('c');
}
int main() {
    cout << "inside main()" << endl;
    f(); // Calls static constructor for b
    // g() not called
    cout << "leaving main()" << endl;
}
 
</iostream>
1
2
3
4
5
6
7
8
9
10
11
12
<p style="margin-top:0px;margin-bottom:0px;padding:0px;font-family:Arial;font-size:14px;line-height:26px;white-space:normal;background-color:#FFFFFF;">
      这个程序的输出是
</p>
 
<p style="margin-top:0px;margin-bottom:0px;padding:0px;font-family:Arial;font-size:14px;line-height:26px;white-space:normal;background-color:#FFFFFF;">
      Obj::Obj() for a
  inside main()
  Obj::Obj() for b
  leaving main()
  Obj::~Obj() for b
  Obj::~Obj() for a
</p>

  有几点值得注意的。

  a是全局静态变量,其构造函数在main之前就被调用。

  b是f()的静态变量,因为f()被调用,所以被初始化。

  c是g()的静态变量,因为g()没被调用,所以没有被初始化。

  静态变量的析构函数都是在main()退出时被调用。顺序相反。


注意事项

  尽量避免静态变量的初始化依赖,如果一定要产生依赖关系的话,最好放到单独一个文件里面,以便控制。

阅读(781) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~