C++ 中的static
关键字
Static 是 C++ 中的一个关键字,用来给元素赋予特殊的特性。静态元素在程序生命周期中只在静态存储区被分配一次存储。他们有一个直到程序生命周期的范围。static
关键字可用于以下情况:
- 函数中的静态变量
- 静态类对象
- 类中的静态成员变量
- 类中的静态方法
函数内部的静态变量
静态变量在函数中使用时只初始化一次,然后即使通过函数调用也保持在那里。
这些静态变量存储在静态存储区,而不是栈中。
void counter()
{
static int count=0;
cout << count++;
}
int main(0
{
for(int i=0;i<5;i++)
{
counter();
}
}
0 1 2 3 4
让我们在不使用静态变量的情况下,se 同一个程序的输出。
void counter()
{
int count=0;
cout << count++;
}
int main(0
{
for(int i=0;i<5;i++)
{
counter();
}
}
0 0 0 0 0
如果我们不使用static
关键字,变量计数将在每次调用counter()
函数时被重新初始化,并在每次counter()
函数结束时被销毁。但是,如果我们将其设为静态,一旦初始化,count 将有一个作用域,直到main()
函数结束,并且它也将通过函数调用携带其值。
如果不初始化静态变量,默认情况下它们被初始化为零。
静态类对象
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";
}
构造器 END 析构器
你一定在想,为什么析构器没有被调用到if
条件范围的末尾,对象obj
的引用应该被销毁。这是因为对象是static
,它的作用域一直持续到程序的生命周期,因此当main()
函数退出时,这个对象的析构器被调用。
类中的静态数据成员
类的静态数据成员是所有对象共享的成员。静态数据成员有一个单独的存储区,不能像其他非静态数据成员一样作为每个对象的单独副本。
静态成员变量(数据成员)不使用构造器初始化,因为它们不依赖于对象初始化。
此外,它必须显式初始化,总是在类之外。如果没有初始化,链接器将给出错误。
class X
{
public:
static int i;
X()
{
// construtor
};
};
int X::i=1;
int main()
{
X obj;
cout << obj.i; // prints value of i
}
one
static
数据成员一旦定义,用户就不能重新定义。不过,算术运算可以在上面进行。
静态成员函数
这些函数对整个类起作用,而不是对类的特定对象起作用。
可以使用对象和直接成员访问.
操作符调用。但是,更典型的是使用类名和作用域解析::
运算符单独调用静态成员函数。
例如:
class X
{
public:
static void f()
{
// statement
}
};
int main()
{
X::f(); // calling member function directly with class name
}
这些函数不能访问普通数据成员和成员函数,只能访问静态数据成员和静态成员函数。
它没有任何“这个”关键字,这就是它无法访问普通成员的原因。我们后面会研究关于“这个”的关键字。