当前位置: 首页 > 知识库问答 >
问题:

静态关键字及其在C++中的各种用法

孟翰海
2023-03-14

根据我的理解,存在static存储持续时间,这意味着在全局的情况下,它会持续到程序的生存期,但是当您谈到局部的情况时,它意味着默认情况下初始化为零。

C++标准对具有关键字statice的类数据成员这样说:

3.7.1静态存储持续时间[basic.stc.Static]

局部变量是什么意思?那是函数局部变量吗?因为当您将函数local声明为statice时,它只在第一次进入该函数时初始化一次。

它也只讨论与类成员有关的存储持续时间,它不是特定于实例的,这也是staticno的属性吗?还是存储时间?

现在使用statice和文件范围的情况如何?默认情况下,是否所有全局变量都被认为具有静态存储持续时间?以下(来自第3.7.1节)似乎表明了这一点:

static如何与变量的链接相关?

这个static关键字简直让人摸不着头脑,有人能澄清一下it英语的不同用法吗,还能告诉我什么时候初始化一个static类成员?

共有1个答案

洪光霁
2023-03-14

static变量对于其定义的翻译单元的“生存期”存在,并且:

  • 如果它在名称空间范围内(即在函数和类之外),则不能从任何其他转换单元访问它。这被称为“内部联动”或“静态存储持续时间”。(除了constexpr之外,不要在头文件中这样做。任何其他文件,最后在每个翻译单元中都有一个单独的变量,这太混乱了)
  • 如果它是函数中的变量,就不能从函数外部访问它,就像任何其他局部变量一样。(这就是他们提到的本地人)
  • 由于 static
  • 类成员没有受限制的作用域,但可以从类和实例中寻址(如std::string::npos)。[注意:您可以在类中声明静态成员,但它们通常仍应在翻译单元(cpp文件)中定义,因此,每个类只有一个成员]

作为代码的位置:

static std::string namespaceScope = "Hello";
void foo() {
    static std::string functionScope= "World";
}
struct A {
   static std::string classScope = "!";
};

正确处理所有这些问题的最简单的方法是使所有不是constexpr的静态变量初始化为函数静态局部变量,这可以确保所有静态变量/全局变量在您尝试使用它们时都正确初始化,从而防止静态初始化顺序的混乱。

T& get_global() {
    static T global = initial_value();
    return global;
}

要小心,因为当规范说命名空间范围变量默认具有“静态存储持续时间”时,它们意味着“翻译单元的生存期”位,但这并不意味着它不能在文件外部访问。

更简单的是,static经常用作类成员函数,很少用于独立函数。

静态成员函数与常规成员函数的不同之处在于,它可以在没有类的实例的情况下被调用,并且由于它没有实例,所以它不能访问类的非静态成员。当您希望为一个绝对不引用任何实例成员的类提供函数时,或者为管理statice成员变量提供函数时,静态变量非常有用。

struct A {
    A() {++A_count;}
    A(const A&) {++A_count;}
    A(A&&) {++A_count;}
    ~A() {--A_count;}

    static int get_count() {return A_count;}
private:
    static int A_count;
}

int main() {
    A var;

    int c0 = var.get_count(); //some compilers give a warning, but it's ok.
    int c1 = A::get_count(); //normal way
}

静态自由函数意味着该函数不会被任何其他翻译单元引用,因此链接器可以完全忽略它。这有几个目的:

  • 可以在cpp文件中使用,以保证该函数永远不会从任何其他文件中使用。
  • 可以放在一个头中,每个文件都有它自己的函数副本。没有用,因为内联做的事情几乎是一样的。
  • 通过减少工作量来加快链接时间
  • 可以在每个翻译单元中放一个同名的函数,它们都可以做不同的事情。例如,您可以在每个cpp文件中放置一个静态无效日志(const char*){},并且它们可以以不同的方式记录。
 类似资料:
  • 本文向大家介绍在C#中global关键字的作用及其用法,包括了在C#中global关键字的作用及其用法的使用技巧和注意事项,需要的朋友参考一下 global 是 C# 2.0 中新增的关键字,理论上说,如果代码写得好的话,根本不需要用到它。 假设你现在写了一个类,名字叫 System。那么当你再在代码里写 System 的时候,编译器就不知道你是要指你写的 System 类还是系统的 System

  • 本文向大家介绍Java中的静态关键字,包括了Java中的静态关键字的使用技巧和注意事项,需要的朋友参考一下 静态修饰符 静态变量 在静态关键字用于创建将独立存在的类创建的所有实例变量。无论类的实例数量如何,静态变量只有一个副本存在。 静态变量也称为类变量。局部变量不能声明为静态。 静态方法 static关键字用于创建将独立于为该类创建的任何实例存在的方法。 静态方法不使用定义它们的类的任何对象的任

  • 本文向大家介绍C# this关键字的四种用法,包括了C# this关键字的四种用法的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了C# this关键字的四种用法,供大家参考,具体内容如下 用法一  this代表当前实例,用this.显式调用一个类的方法和成员 用法二  通过this实现原始类型的扩展(下一篇详解) 用法三  通过this实现索引器,可用于优化程序性能(下一篇详解) 用

  • 本文向大家介绍详解C/C++中const关键字的用法及其与宏常量的比较,包括了详解C/C++中const关键字的用法及其与宏常量的比较的使用技巧和注意事项,需要的朋友参考一下 1.const关键字的性质 简单来说:const关键字修饰的变量具有常属性。 即它所修饰的变量不能被修改。 2.修饰局部变量 这两种写法是等价的,都是表示变量的值不能被改变,需要注意的是,用const修饰变量时,一定要给变量

  • 静态在下面有意义吗(我来自Java背景)?它会编译,但惯例/标准是什么?

  • 本文向大家介绍DBMS中的各种键,包括了DBMS中的各种键的使用技巧和注意事项,需要的朋友参考一下 DBMS中不同类型的键是- 候选键- 表中的候选键定义为最小的键集,可以唯一地标识表中的任何数据行。 主键- 主键是从候选键之一中选择的,并成为表的标识键。它可以唯一地标识表的任何数据行。 超级键- 超级键是主键的超集。超级键包含一组属性,包括主键,可以唯一地标识表中的任何数据行。 复合键- 如果表