原文链接:Static Keyword in C++

static 是 C++ 中的关键字,用于为元素赋予特殊的特性。静态元素在程序生存期内仅在静态存储区中分配一次存储。它们一直作用到程序生存期。静态关键字可以与以下内容一起使用,

  1. 函数中的静态变量
  2. 静态类对象
  3. 类中的静态成员变量
  4. 类中的静态方法

1. 函数中的静态变量

在函数内部使用静态变量时,仅初始化一次,然后即使通过函数调用,它们也保留上次调用的结果值。

这些静态变量存储在静态存储区中,而不是栈中。

void counter()
{
static int count = 0;
cout << count++;
}

int main(0
{
for(int i = 0;i < 5; i++)
{
counter();
}
}
Output: 0 1 2 3 4

不使用静态变量的相同程序的输出。

void counter()
{
int count = 0;
cout << count++;
}

int main(0
{
for(int i = 0; i < 5; i++)
{
counter();
}
}
Output: 0 0 0 0 0

如果我们不使用 static 关键字,那么每次调用 counter() 函数时,变量 count 都会重新初始化,并在 counter() 函数结束时被销毁。但是,如果我们将其设为 staticcount 一旦初始化就会一直作用到 main() 函数的结尾,并且它也将通过函数调用保留其值。

如果不初始化静态变量,则默认情况下会将它们初始化为零。

2. 静态类对象

static 关键字对类对象的工作方式也相同。声明为 static 的对象将分配到静态存储区中,并且一直作用到程序结束。

静态对象也使用和其他普通对象一样的构造函数进行初始化。使用 static 关键字分配为零仅适用于原始数据类型,不适用于用户定义的数据类型。

class Abc
{
int i;
public:
Abc()
{
i=0;
cout << "constructor";
}
~Abc()
{
cout << "destructor";
}
};

void f()
{
static Abc obj;
}

int main()
{
int x=0;
if(x==0)
{
f();
}
cout << "END";
}
Output: constructor END destructor

你肯定会想,为什么在 if 条件范围结束时不调用析构函数来销毁 obj 对象。这是因为对象是静态的,其作用于程序的整个生命周期,因此在 main() 函数退出时将调用此对象的析构函数。

3. 类中的静态成员变量

类中的静态成员变量被所有的类对象所共享,静态成员只有一个存储空间,不能像其他非静态成员一样作为每个对象的单独副本使用。

静态成员变量不使用构造函数初始化,因为它们不依赖于对象初始化。

另外,必须显式初始化,通常在类外进行初始化。如果未初始化,链接器将给出错误。

class X
{
public:
static int i;
X()
{
// construtor
};
};

int X::i=1;

int main()
{
X obj;
cout << obj.i; // prints value of i
}
Output: 1

一旦定义了静态数据成员,用户便无法重新定义它。但是,可以对其执行算术运算。

4. 类中的静态方法

这些方法适用于整个类,而不是类的特定对象。可以使用直接成员访问 . 来调用它。但是,使用类名和作用域解析 :: 运算符调用静态成员函数更为典型。

class X
{
public:
static void f()
{
// statement
}
};

int main()
{
X::f(); // calling member function directly with class name
}

这些函数不能访问普通成员变量和成员函数,而只能访问静态成员变量和静态成员函数。