在C ++中声明“全局”变量时,“静态”究竟意味着什么?

时间:2010-08-05 16:05:46

标签: c++ static-variables static

这是previous question of mine范围的扩展。

究竟什么是“静态”,它是如何使用的,以及在处理C ++时使用“静态”的目的是什么?

感谢。

6 个答案:

答案 0 :(得分:13)

这意味着变量是翻译单元的本地变量(简单地放到单个源文件中),并且不能从外部访问。事实上,在当前的C ++标准中不推荐使用静态 - 而是应该使用匿名命名空间:

static int x = 0;    

应该是:

namespace {
    int x = 0;    
}

答案 1 :(得分:10)

关键字static在C ++中具有不同的含义,具体取决于上下文。

声明自由函数或全局变量时,意味着该函数不能在此单个翻译单元之外使用:

// test.cpp
static int a = 1;
static void foo() {}

如果编译该翻译单元的结果与包含符号afoo的其他翻译单元相关联,则不会破坏单一定义规则,如此特定翻译单元{{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。在示例程序xt.x中引用不同的整数。另一方面,other.xy,因此程序中只有static的单个实例。即使标准允许调用test::yt.y,两个用法也会引用相同的变量。成员方法也是如此。如果它们是静态的,则它们是类级方法,可以在没有实例的情况下调用,而如果它们是非静态的,则它们应用于具体实例,并且必须使用other.ya.b语法。

a->b的这种使用类似于在Java中使用相同的关键字,而其他两种在该语言中不存在。在Java中有一个关键字在C ++中没有使用,那就是使用静态类初始值设定项(类static所包含的类级别的代码块)。在Java中,当加载类时只执行一次代码块。必须在变量定义的初始值设定器中初始化C ++中的静态成员变量。

答案 2 :(得分:6)

这些东西似乎覆盖得很好here

但是为了解释,C中有2种用途

  1. 防止在定义它的文件范围之外使用全局变量。
  2. 允许函数中的局部变量在函数调用时保持不变,如

    int getNextId() {   static int id = 0;   return id ++; }

  3. C ++继承了这两者,并增加了两种用途。

    1. 静态成员变量:在所有类的实例中“共享”的变量,也可以在不引用类的实例的情况下进行访问。共享似乎是错误的单词,但实质上我相信结果是对静态成员变量的任何引用都引用相同的内存位置。
    2. 静态方法:可以在不引用定义它的类的特定实例的情况下调用的方法。

答案 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)。