这是我之前的问题范围的扩展。
究竟什么是“静态”,它是如何使用的,在处理 C++ 时使用“静态”的目的是什么?
谢谢。
这意味着该变量对于翻译单元是本地的(简单地说,对于单个源文件),并且不能从其外部访问。这种使用 static 实际上在当前的 C++ 标准中已被弃用 - 相反,您应该使用匿名命名空间:
static int x = 0;
应该:
namespace {
int x = 0;
}
关键字static
在 C++ 中具有不同的含义,具体取决于上下文。
声明自由函数或全局变量时,意味着该函数在此单个翻译单元之外不可用:
// test.cpp
static int a = 1;
static void foo() {}
如果编译该翻译单元的结果与包含符号的不同翻译单元链接,a
并且foo
它不会违反单一定义规则,如在此特定翻译单元中a
并且foo
是私有符号。这种用法已被未命名的命名空间淘汰。
// test2.cpp
namespace {
static int a = 1;
static void foo() {}
}
在函数中声明局部变量时,这意味着变量的生命周期将从第一次调用函数到程序结束,而不仅仅是在调用期间:
int foo() {
static int counter = 0;
return ++counter;
}
int main() {
for ( int i = 0; i < 10; ++i ) {
std::cout << foo() << std::endl;
}
}
在前面的代码中,第一次调用counter
时会初始化一次foo
,但变量会比函数寿命更长,并在不同的函数调用中保持值。前面的代码将打印“1 2 3 4...10”。如果未声明变量,static
则输出将为“1 1 1...1”。
在类范围内,static
意味着该成员是类的成员,而不是特定实例的成员。这种用法等同于您在其他问题中的用法:该特定成员的用法不绑定到任何特定对象。
struct test {
int x;
static int y;
};
int test::y; // need to define it in one translation unit
int main() {
// test::x = 5; // !error cannot access a non-static member variable
// without an instance
test::y = 5; // ok
test t, other;
t.x = 10; // ok
t.y = 15; // ok, the standard allows calling a static member through
// an instance, but this is the same as test::y
}
在这种情况下,成员x
是一个非静态成员属性,因此x
类的每个实例都有不同的属性。在示例程序中t.x
并other.x
引用不同的整数。另一方面y
是static
,因此程序中有一个实例test::y
。即使标准允许调用t.y
并且other.y
两种用法都引用同一个变量。成员方法也是如此。如果它们是静态的,它们是类级别的方法,可以在没有实例的情况下调用,而如果它们是非静态的,它们将应用于具体实例并且必须使用a.b
or语法。a->b
这种使用static
类似于 Java 中使用相同的关键字,而其他两个在该语言中不存在。Java 中有一个关键字在 C++ 中不存在,即使用静态类初始化器(类级别的代码块,由 包围static { ... }
)。在 Java 中,该代码块将在加载类时执行一次,并且只执行一次。C++中静态成员变量的初始化必须在变量定义的初始化器中完成。
这些东西似乎在这里得到了很好的介绍。
但解释一下,C 中有 2 个用途
允许函数内的局部变量在函数的调用中保持不变,如
int getNextId() { 静态 int id = 0; 返回 id++; }
C++ 继承了这两者,并添加了自己的两个用途。
静态基本上意味着变量与程序的生命周期相关,而不是任何给定的函数或类实例。你应该什么时候使用它?不。什么目的?主要是调试数据。
通常,在 C++ 中,如果您发现自己使用静态数据,那么您就做错了。有时它是合适的,但它们非常罕见。
当在 C++ 中的类中使用 static 时,它的含义或多或少与 Java 中的相同。对于变量,这意味着所有类都存在一个变量实例,对于函数,这意味着函数根本不会隐式访问 this 指针。
在 C 和 C++ 中,当静态用于全局变量或函数时,这意味着该变量只能在当前 C 或 C++ 文件中被引用。换句话说,编译器不得为变量或函数生成任何重定位符号。
当在局部函数中的变量旁边使用静态时,这意味着该变量不会超出范围,但会在函数调用到函数调用时保留其值。该变量实际上成为一个只能从给定函数访问的全局变量。
静态类成员是与类本身相关联的数据和函数,而不是与类的对象相关联。
在下面的示例中,Fred 类有一个静态数据成员 x_ 和一个实例数据成员 y_。无论创建了多少 Fred 对象(包括没有 Fred 对象),Fred::x_ 都只有一份副本,但每个 Fred 对象都有一个 y_。因此,x_ 被称为与类相关联,而 y_ 被称为与类的单个对象相关联。类似地,Fred 类有一个静态成员函数 f() 和一个实例成员函数 g()。
class Fred {
public:
static void f() throw(); <-- 1
void g() throw(); <-- 2
protected:
static int x_; <-- 3
int y_; <-- 4
};
(1) 与类关联的成员函数
(2) 与类的单个对象关联的成员函数
(3) 与类关联的数据成员
(4) 与类的单个对象关联的数据成员
用法:
当您想了解创建的类的实例数量时,您可以使用静态变量。例如,在“Car”类中,每个 Car 实例可能有一个唯一的序列号(在这种情况下为 _y),公司可能希望跟踪生产的汽车数量(在这种情况下为 _x)。