【问题标题】:static in different languages不同语言的静态
【发布时间】:2009-03-06 19:02:26
【问题描述】:

我听说不同语言对关键字 static 的含义存在差异,但我没有找到一个很好的列表来整合这些差异。

以下是我对C++中static的含义的了解:

  • 对于函数内的局部静态变量,变量在启动时初始化,值在函数调用之间保存。
  • 静态数据成员在类的所有实例之间共享。换句话说,静态数据成员只有一个实例。静态数据成员必须在文件范围内初始化。
  • 静态成员函数只能访问静态成员。
  • 在递归代码中,静态对象或变量保证在代码块的不同实例中具有相同的状态。
  • 在文件范围内定义的静态对象和变量只有内部链接。其他文件不得使用它们。

static在其他语言中的含义有何变化?

【问题讨论】:

  • C++ 中的静态局部变量在第一次调用时被初始化,而不是在启动时。
  • @Iraimbilanja,你能给我一个参考吗? MSDN 似乎另有建议。
  • @Iraimbilanja:C&V 6.7(具体内容请参见我的帖子)。
  • scottie: 好吧... struct A { A() { cout
  • 当然,这只是意味着输出是按顺序执行的。这并不能证明结构在启动时没有被初始化。老实说,我对任何一个答案都没有投资,我只是想知道正确的答案。

标签: programming-languages static keyword


【解决方案1】:

C


  • 关键字可以更改对象的链接或持续时间(生命周期)。
  • 变量总是初始化为 0
  • 函数具有内部链接。
  • 如果在文件级范围内声明:变量具有内部链接和静态持续时间(即在程序的整个生命周期中都存在)
  • 如果在块范围内声明:变量没有链接但静态持续时间
  • 在一个翻译单元中可以有同一个静态变量的多个声明。但是,请注意它们必须相同。例如:在文件级范围内:

int a;        // a has external linkage

static int a; // a now has static linkage
              // same as if you wrote: static int a = 0;

//...

static int b; // static linkage

extern int b; // extern loses its meaning, b still has internal linkage

//...

extern int b; // b has external linkage

static int b; // error

//...

void func() {
  static int x; // automatic linkage, static duration
                // same as if you wrote: static int x = 0;
}

C++


  • 在文件级别范围内,已弃用变量和成员的用法,而支持匿名命名空间。仅作为兼容性存在
  • 变量仍被默认初始化(如在 C 中)为 0
  • "6.7 在任何其他初始化发生之前执行所有具有静态存储持续时间 (3.7.1) 或线程存储持续时间 (3.7.2) 的本地对象的零初始化 (8.5) [...] "
  • 变量具有静态存储持续时间,除非伴随 thread_local 说明符(从 C++0x 开始)
  • 翻译单元中只能有一个静态定义
  • 成员变量/函数意味着它们是类的属性而不是实例 合法访问语法:instance.property 或 Class::property
  • 静态成员函数只能访问静态成员变量 此类函数没有this 指针
  • 但非静态成员可以访问任何静态成员
  • 在文件级别,对象具有内部链接,但具有类作用域的类成员除外
  • 需要在类声明中或外部通过类名和范围解析运算符显式定义类成员
  • 不能在静态方法中使用this

动作脚本


  • C++ 中的类方法
  • 不能在静态方法中使用thissuper
  • 只能通过类名而不是实例名访问
  • 未继承
  • 派生类可以访问基类的静态属性
  • 使用 static 和 const 关键字声明的变量必须在声明常量的同时初始化

面向对象设计


  • Singleton 设计模式被许多人视为美化的静态对象
  • 用于工厂设计模式

我可能错过了很多其他的东西——请随意加入。

【讨论】:

  • 多年后的崩塌:C++ 文件范围静态弃用已不复存在。
【解决方案2】:

在 Delphi 中,static 关键字专门用于定义类方法。在 Delphi 中,normal 类方法可以声明为虚拟方法并在子类中覆盖。此外,Delphi 有一个 self 变量,类似于其他语言中的 this 指针。然而,在类方法中,self 指向调用该方法的类而不是实例。

声明一个类方法static的意思是:

  1. 它不能在子类中被覆盖
  2. 它没有self指针

这意味着静态类方法只能访问定义它的类中的类成员,而普通类方法可以访问派生类中被覆盖的类成员。

在 Delphi 文档中还有其他非正式的静态用法,通常指的是特性的不可更改性(这是一个词吗?)。例如静态数组与动态数组。 Delphi 中的所有实例方法都是静态的,除非另有声明。

【讨论】:

  • 另外值得注意的是,在较新的 Delphi 版本中,对于记录中的类函数是强制性的 static
【解决方案3】:

在 C# 中,它几乎总是意味着:“与类型相关,而不是类型的实例”。

【讨论】:

  • @R Bemrose - 差不多。 “静态导入”感觉不太一样;例如,它肯定不是非静态导入的“类型等价物”。
  • 但是扩展方法,总是“与类型的实例相关”,只能在静态类中声明......打破了好的经验法则。
  • 嗯,有点 - 有点不是。在这种情况下,实例作为参数提供。关键是没有固有的上下文。
【解决方案4】:

在 VB.NET 中,Static 变量就像 C++ 局部静态变量。

但是,没有类范围的Static;请改用Shared

【讨论】:

    【解决方案5】:

    在 C# 中有 3 种方式可以使用静态关键字:

    • 在类定义上,表示类只会暴露静态成员,不能实例化
    • 在类成员上,这意味着无需实例化类即可调用该成员。
    • 在构造函数上,这意味着静态构造函数总是在调用静态成员之前被调用。 (这些主要是性能瓶颈,因此不推荐)

    希望这会有所帮助。

    【讨论】:

    • 别忘了在类定义上也意味着类可以声明扩展方法。此外,“无需实例化类即可调用”是一种非常非正统的描述方式。而在构造函数上,重要的是它变成了“类构造函数”吗?
    • 如果你有一个有 3 个静态成员和一个静态构造函数的类,静态构造函数总是在静态成员执行之前调用,每次调用一个成员。这与类构造器不同,因为类构造器只有在类被实例化时才会被调用。
    【解决方案6】:

    Python 有装饰器@staticmethod,当应用于类成员时,使方法在类而不是实例上可用,并且不向方法传递自动参数。 @classmethod 装饰器执行类似的功能,但将类作为第一个参数传递,使其更加有用。

    【讨论】:

      【解决方案7】:

      在 C 中,静态将函数或全局变量标记为其所在文件的本地变量。

      这有点像其他语言中的私有。排序。

      如果它在函数中,则静态在二进制文件的数据部分中预分配该变量,而不是在运行时在堆栈中。

      【讨论】:

        【解决方案8】:

        在 VB.NET 中,静态用于过程级别,表示变量与过程的所有执行相关联(它在调用之间保留)。不过,这在面向对象的应用程序中有点晦涩难懂。

        对应的是“共享”,这意味着方法或成员是类型级别的(您不需要实例来访问它)。

        【讨论】:

          【解决方案9】:

          维基百科总结了static的许多不同含义:

          Static Methodsstatic variablesstatic typing

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-01-13
            • 2013-05-30
            • 2013-08-11
            • 1970-01-01
            • 2012-09-17
            • 1970-01-01
            • 2014-01-24
            • 2012-01-26
            相关资源
            最近更新 更多