答案 0 :(得分:13)
这意味着变量是翻译单元的本地变量(简单地放到单个源文件中),并且不能从外部访问。事实上,在当前的C ++标准中不推荐使用静态 - 而是应该使用匿名命名空间:
static int x = 0;
应该是:
namespace {
int x = 0;
}
答案 1 :(得分:10)
关键字static
在C ++中具有不同的含义,具体取决于上下文。
声明自由函数或全局变量时,意味着该函数不能在此单个翻译单元之外使用:
// test.cpp
static int a = 1;
static void foo() {}
如果编译该翻译单元的结果与包含符号a
和foo
的其他翻译单元相关联,则不会破坏单一定义规则,如此特定翻译单元{{1} }和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
时初始化一次,但变量将比函数更长,并将值保持在不同的函数调用之间。之前的代码将打印“1 2 3 4 ... 10”。如果变量未声明为foo
,那么输出将为“1 1 1 ... 1”。
在类范围内,static
表示该成员是该类的成员,而不是特定实例的成员。此用法等同于您在其他问题中的用法:该特定成员的使用不受任何特定对象的约束。
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
语法。
a->b
的这种使用类似于在Java中使用相同的关键字,而其他两种在该语言中不存在。在Java中有一个关键字在C ++中没有使用,那就是使用静态类初始值设定项(类static
所包含的类级别的代码块)。在Java中,当加载类时只执行一次代码块。必须在变量定义的初始值设定器中初始化C ++中的静态成员变量。
答案 2 :(得分:6)
这些东西似乎覆盖得很好here。
但是为了解释,C中有2种用途
允许函数中的局部变量在函数调用时保持不变,如
int getNextId() { static int id = 0; return id ++; }
C ++继承了这两者,并增加了两种用途。
答案 3 :(得分:2)
静态基本上意味着变量与程序的生命周期相关联,而不是与任何给定的函数或类实例相关联。你应该什么时候使用它?别。什么目的?主要是调试数据。
通常,在C ++中,如果您发现自己使用的是静态数据,那么您做错了。有时候这是合适的,但它们非常罕见。
答案 4 :(得分:1)
当在C ++中的类中使用静态时,它或多或少与Java中的相同。对于变量,它意味着所有类和函数都存在一个变量实例,这意味着该函数根本不会隐式访问该指针。
在C和C ++中,当static用于全局变量或函数时,则意味着该变量只能在当前的C或C ++文件中引用。换句话说,编译器不得为变量或函数生成任何重定位符号。
当在本地函数中的变量旁边使用static时,这意味着该变量不会超出范围,但会将其值从函数调用保留到函数调用。变量实际上变为一个只能从给定函数访问的全局变量。
答案 5 :(得分:0)
静态类成员是与类本身相关联的数据和函数,而不是与类的对象相关联。
在以下示例中,类Fred具有静态数据成员x_和实例数据成员y_。 Fred :: x_只有一个副本,无论创建了多少Fred对象(包括没有Fred对象),但每个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)与班级的单个对象相关联的数据成员
<强>用法:强>
如果要保留创建的类的实例数,请使用静态变量。例如,在“汽车”类中,每个汽车实例可能具有唯一的序列号(在这种情况下为_y),公司可能希望跟踪生产的汽车数量(在这种情况下为_x)。