static关键字及其在C中的各种用法

关键字static是一个在C中有几个含义,我觉得很混乱,我永远不能弯曲我的思想,实际上应该如何工作。

从我的理解是有静态存储持续时间,这意味着它持续的程序的生命周期的全局,但是当你谈论一个本地,这意味着它的默认初始化零。

C标准对具有关键字static的类数据成员说:

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

3 The keyword static can be used to declare a local variable with static storage duration.

4 The keyword static applied to a class data member in a class definition gives the data member static storage duration.

局部变量是什么意思?这是一个函数局部变量吗?因为还有一个问题,当你将一个函数local声明为static,它只被初始化一次,第一次进入这个函数。

它也只谈到关于类成员的存储持续时间,什么是非实例特定的,这也是静态否的属性?还是那个存储持续时间?

现在关于静态和文件范围的情况怎么样?默认情况下,所有全局变量都被视为具有静态存储持续时间以下(从3.7.1节)似乎表明:

1 All variables which do not have dynamic storage duration, do not have thread storage duration, and are not local have static storage duration. The storage for these entities shall last for the duration of the program (3.6.2, 3.6.3)

静态与变量的联系如何相关?

这整个静态关键字是彻底的混乱,有人可以澄清它的不同用途的英语,并告诉我什么时候初始化一个静态类成员?

变量:

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

>如果它在一个命名空间范围(即在函数和类之外),那么它不能从任何其他翻译单元访问。这被称为“内部连接”。 (不要这样做的标题,这只是一个可怕的想法)
>如果它是一个函数中的变量,它不能从函数外部访问,就像任何其他局部变量一样。 (这是他们提到的地方)
>类成员由于静态没有受限范围,但可以从类以及实例(如std :: string :: npos)寻址。 [注意:你可以在类中声明静态成员,但是它们通常仍然在翻译单元(cpp文件)中定义,因此,每个类只有一个]

在翻译单元中的任何函数被执行之前(可能在主开始执行之后),在该翻译单元中具有静态存储持续时间的变量将是“常量初始化”(在可能的情况下为constexpr,否则为0),然后非本地按照它们在翻译单元中定义的顺序(例如std :: string =“HI”;不是constexpr)正确地“动态初始化”。最后,函数局部静态在第一次执行“到达”它们被声明的行时被初始化。它们都以与初始化相反的顺序被破坏。

获得所有这些权利的最简单的方法是使所有非constexpr的静态变量初始化为函数静态局部变量,这将确保所有的静态/全局变量正确初始化时,无论什么,因此阻止static initialization order fiasco

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

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

功能

明显更直接,静态通常用作类成员函数,并且仅非常少用于独立函数。

静态成员函数不同于常规成员函数,因为它可以在没有类的实例的情况下被调用,并且由于它没有实例,它不能访问类的非静态成员。当你想要一个绝对不引用任何实例成员的类的函数,或者管理静态成员变量时,静态变量是有用的。

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文件中使用,以保证该函数不会从任何其他文件使用。
>可以放在标题中,每个文件都有自己的函数副本。没有用,因为内联几乎是一样的东西。
>通过减少工作速度加快链接时间
>可以在每个TU中放置具有相同名称的函数,并且它们都可以做不同的事情。例如,你可以在每个cpp文件中放置一个静态无效日志(const char *){},并且它们都可以以不同的方式登录。

http://stackoverflow.com/questions/15235526/the-static-keyword-and-its-various-uses-in-c

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:static关键字及其在C中的各种用法