static 关键字的用法

1.用在函数内,在多次调用间,保持值不变

void func() {
    static int i = 0;
    cout << "i = " << ++i << endl;
}
int main() {
    for(int x = 0; x < 10; x++)
        func();
} ///:~

函数func中的i只会在第一次被调用时,初始化一次。

如果不明确写出初始化的值,也可以,编译器会自动默认赋值为0。

如果是class,如果不制定构造函数,那就需要有默认构造函数了。

 

2. 表示静态链接

用static标示的 函数 或者 变量 ,不能被文件外的文件链接到。

 

 

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

 

#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;
} ///:~
上面这个程序的输出是

Obj::Obj() for a
inside main()
Obj::Obj() for b
leaving main()
Obj::~Obj() for b
Obj::~Obj() for a

 

所以有几点值得注意的。

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

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

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

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

 

 

4。类中的静态成员变量

#include <iostream>
using namespace std;
int x = 100;
class A
{
public:
    A(int d):a(d) {}
    int a;
};
class WithStatic {
   static int x;
   static int y;
   static A   a;

public:
   void print() const {
     cout << "WithStatic::x = " << x << endl;
     cout << "WithStatic::y = " << y << endl;
   }
};
int WithStatic::x = 1;
int WithStatic::y = x + 1;
A   WithStatic::a(100);

// WithStatic::x NOT ::x
int main() {
   WithStatic ws;
   ws.print();
} ///:~
静态成员变量 一定要在definition的地方,也就是cpp文件中定义。
而且需要注意的是 WithStatic::y = x + 1;  最后这个y等于 2 而不是101!

 

5. static arrays in class

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),必须在类外定义。

 

6.static functions in class

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

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

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
} ///:~

 

7. static initialization dependency

静态对象初始化的顺序是一个比较trick的问题。 如果两个静态对象有依赖关系,那么就有可能产生不可预知的问题。

 

1. Don’t do it. Avoiding static initialization dependencies is the
    best solution.不这么做
2. If you must do it, put the critical static object definitions in a
    single file, so you can portably control their initialization by
    putting them in the correct order.放入一个文件
3. If you’re convinced it’s unavoidable to scatter static objects
    across translation units – as in the case of a library, where
    you can’t control the programmer who uses it – there are two
    programmatic techniques to solve the problem.两种方法

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值