【问题标题】:Difference between static in C and static in C++??C中的静态和C ++中的静态之间的区别??
【发布时间】:2010-10-30 21:45:36
【问题描述】:

C 和 C++ 中的 static 关键字有什么区别?

【问题讨论】:

  • 我不是在询问类成员(数据或函数)静态部分。在 C 和 C++ 的文件范围内定义的静态变量的语义有什么不同吗??

标签: c++ c


【解决方案1】:

static 关键字在 C 和 C++ 中的用途相同。

  1. 在文件级别(函数外部)使用时,它设置应用它的项目的可见性。静态项在其编译单元之外不可见(例如,对于链接器)。它们的持续时间与程序的持续时间相同。

    这些文件级项目(函数和数据)应该是静态的,除非有特殊需要从外部访问它们(并且几乎不需要直接访问数据,因为这破坏了封装的核心原则)。
    如果(正如您对问题的评论所示)这是您所关心的 static 的唯一用途,那么,不,C 和 C++ 之间没有区别。

  2. 在函数中使用时,它设置项目的持续时间。同样,持续时间与程序相同,并且该项目在该函数的调用之间继续存在。

    它不会影响该项目的可见性,因为它仅在函数内可见。一个例子是一个随机数生成器,它需要在调用之间保持其种子值,但不希望该值对其他函数可见。

  3. C++ 还有一个用途,static 在一个类中。当在那里使用时,它成为一个单一的类变量,在该类的所有对象中都是通用的。一个经典示例是存储已为给定类实例化的对象的数量。

正如其他人所指出的,文件级静态的使用已被弃用,取而代之的是未命名的命名空间。但是,我相信在它真正从语言中删除之前,在某个温暖的地方会是一个寒冷的日子——目前使用它的代码太多了。并且 ISO C 只是刚刚移除了 gets(),尽管我们都知道这是一个危险的函数。

即使它已被弃用,也不会改变其语义现在

【讨论】:

  • 虽然文件级别的静态在限制文件可见性方面与未命名命名空间的目的相同,但还是有区别的。静态的有内部链接,而未命名的命名空间有外部链接(但由于名称修改,仍然无法从外部访问)未命名命名空间的外部链接对于允许在未命名命名空间中声明的类型用作模板参数是必要的。跨度>
  • 3/ 可以这样写:“静态将类变量的持续时间设置为与程序相同。静态不会影响变量的可见性,因为它已经只在类中可见。”由于您的帖子,我在所有 3 个枚举中都发现了静态的这个共同特征。以前没有看到这个。 +1
  • 一点我必须 2/ - 在 C++ 函数级静态变量中,不是 POD 或未使用常量初始化的变量在控制通过其声明之前不会存在。这一点很重要,因为与 C 中只允许常量初始化它们不同,在 C++ 中情况并非如此,在这里,构造函数也可能导致其他副作用。
  • "...永远不需要..." :-)
【解决方案2】:

在文件范围内使用 static 来限制对当前翻译单元的访问在 C++ 中已弃用,但在 C 中仍然可以接受。

改为使用未命名的命名空间

namespace
{
    int file_scope_x;
}

以这种方式声明的变量仅在文件中可用,就像它们被声明为静态一样。

弃用的主要原因是删除 static 关键字的几个重载含义之一。

最初,这意味着变量(例如在函数中)将在程序的生命周期中存储在此类变量的区域中,而不是像通常用于函数局部变量的那样存储在堆栈中。

然后关键字被重载以应用于文件范围链接。根据需要组成新关键字是不可取的,因为它们可能会破坏现有代码。所以这个变量再次以不同的含义使用而不会引起冲突,因为声明为静态的变量不能同时在函数内部和顶层,并且函数之前没有修饰符。 (当提到函数时,存储的含义就完全消失了,因为它们没有存储在任何地方。)

当类出现在 C++(以及 Java 和 C#)中时,该关键字再次被使用,但其含义至少更接近最初的意图。以这种方式声明的变量存储在全局区域中,而不是像函数变量那样存储在堆栈中,或者像对象成员那样存储在堆中。因为变量不能同时位于顶层和类定义中,所以可以明确地将额外的含义附加到类变量上。它们只能通过类名或从该类的对象中引用。

【讨论】:

  • “export”关键字值得一读。导出的一个意想不到的副作用是,一个翻译单元中的导出模板可以引用未命名命名空间中的对象和函数!它实际上提出了 C++ 委员会必须在命名空间对象上重新设置静态的可能性,因为没有它,就无法确保这些变量对其他翻译单元不可见。
  • 需要注意的是,从 C++11 开始,文件范围静态弃用已被删除,尽管它仍然不能用于类型。不过,未来可能会有更多变化。
【解决方案3】:

它在两种语言中的含义相同。

但是 C++ 增加了类。在类(以及结构)的上下文中,它具有使方法/变量类成员而不是对象成员的额外含义。

class Plop
{
    static int x; // This is a member of the class not an instance.

    public:
    static int getX() // method is a member of the class.
    {
        return x;
    }
};

int Plop::x  = 5;

【讨论】:

  • 但在 C++ 中不推荐在顶层使用静态。在 C 中很好。
  • 它肯定已被弃用(附件 D.2),但是,它仅在命名空间范围内的对象中被弃用。
  • 查看 Pax 帖子。这个额外的含义类似于静态的所有含义。关键字影响所有场景中变量的可见性和持续时间,无论是文件、函数还是类。所有这些场景背后都有相同的规则。
【解决方案4】:

请注意,使用 static 来表示“文件范围”(也称为命名空间范围)仅被 C++ 标准反对用于对象,而不是用于函数。换句话说,:

// foo.cpp  
static int x = 0;               // deprecated
static int f() { return 1; }    // not deprecated

引用标准的附录 D:

static关键字的使用是 在声明对象时不推荐使用 命名空间范围。

【讨论】:

    【解决方案5】:

    您不能在 C 中的结构内声明静态变量...但在 Cpp 中允许在范围解析运算符的帮助下。

    在 Cpp 中静态函数也只能访问静态变量,但在 C 中静态函数可以有静态和非静态变量...?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-11
      • 2018-12-22
      • 1970-01-01
      相关资源
      最近更新 更多