寻找严肃、沉默和专注的力量。
分类: C/C++
2013-02-02 16:45:20
低于类级
1.与c语言里面的用法一致,用static标示的函数或者变量,不能被外部文件extern引用(即使编译不报错,链接时也会报错)。
2.static的第二个作用是保持变量内容的持久,存储在静态数据区的变量会在程序刚开始运行时就完成初始化。例子很多,类似全局变量。
类级
3.类的静态普通成员变量
静态成员变量一定要放在definition的地方,也就是cpp文件中定义。
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;
}
};
int WithStatic::x = 1;
A WithStatic::a(100);
int main()
{
WithStatic ws;
ws.print();
}
4.类的静态数组或自定义成员变量
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指针。
非静态成员函数可以访问静态成员变量和静态成员函数。
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.静态对象的构造函数和析构函数
#includeusing 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()退出时被调用。顺序相反。
注意事项
尽量避免静态变量的初始化依赖,如果一定要产生依赖关系的话,最好放到单独一个文件里面,以便控制。