全部博文(2759)
分类: 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()退出时被调用。顺序相反。
注意事项
尽量避免静态变量的初始化依赖,如果一定要产生依赖关系的话,最好放到单独一个文件里面,以便控制。