static关键字及其在C ++中的各种用法 [英] The static keyword and its various uses in C++

查看:179
本文介绍了static关键字及其在C ++中的各种用法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



根据我的理解,有 static 存储持续时间,这意味着它持续的程序的生命周期的情况下一个全局的,但是当你在谈论一个局部的时候,这意味着它默认为零初始化。



C ++标准对类数据成员使用关键字 static



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


3关键字static可用于声明具有静态存储持续时间的局部变量。



4在类定义中应用于类数据成员的关键字static给予数据成员静态存储持续时间。


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



它还仅仅谈到类成员的存储持续时间,它是非实例特定的,这也是 static 否的属性?

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


1没有动态存储持续时间的所有变量,线程存储持续时间,并且不是本地有静态存储持续时间。这些实体的存储将持续程序期间(3.6.2,3.6.3)


如何 static 涉及到变量的链接?



这整个 static 关键字是彻头彻尾的混乱,有人可以澄清它的英语的不同用法, em> when 初始化 static 类成员?

解决方案

变量:



static 定义的翻译单元的生命周期存在变量:




  • 如果它在命名空间范围(即函数和类之外),则无法从任何其他翻译单元访问。这被称为内部连接。 (不要在头文件中这样做,这只是一个可怕的想法)

  • 如果是函数中的变量,则无法从外部访问函数,就像任何其他局部变量一样。 (这是他们提到的本地化)

  • 由于 static ,类成员没有受限范围,作为一个实例(如 std :: string :: npos )。 [注意:您可以在类别中声明静态成员,但通常仍应在翻译单位(cpp文件)中定义,因此,类]



在执行翻译单元中的任何函数之前(可能在 main 开始执行),那么在该转换单元中具有静态存储持续时间的变量将是常量初始化(在可能的情况下为 constexpr ,否则为零),然后非本地( std :: string =HI; 之类的)中正确地动态初始化不是 constexpr )。最后,函数局部静态在第一次执行到达它们被声明的行时被初始化。



获取所有这些权利的最简单的方法是使所有静态变量不是 constexpr 初始化为函数静态局部变量,这将确保所有的静态/全局变量被正确初始化,当你尝试使用它们,无论什么,从而阻止静态初始化顺序fiasco

  get_global(){
static T global = initial_value();
return global;注意,因为当规范说命名空间范围变量有静态存储器默认情况下,它们意味着翻译单元的生命周期位,但这不是
意味着它不能在文件之外访问。



函数



非常简单, static 通常用作类成员函数,很少用于独立功能。



静态成员函数不同于普通成员函数,因为它可以在没有类的实例的情况下被调用,并且由于它没有实例,静态成员的类。当你想为一个绝对不指向任何实例成员或管理成员变量的类创建一个函数时,静态变量是非常有用的。

  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(); //一些编译器给出警告,但它是确定。
int c1 = A :: get_count(); // normal way
}

A static free-function意味着该函数不会被任何其他翻译单元引用,因此链接器可以完全忽略它。这有很少的目的:




  • 可以在cpp文件中使用,以保证该函数不会从任何其他文件使用。

  • 可以放在标题中,每个文件都有自己的函数副本。

  • 通过减少工作速度来缩短链接时间

  • 可以将具有相同名称的函数每个TU,他们可以做不同的事情。例如,你可以在每个cpp文件中放置一个 static void log(const char *){} ,并且每个都可以以不同的方式登录。


The keyword static is one which has several meanings in C++ that I find very confusing and I can never bend my mind around how its actually supposed to work.

From what I understand there is static storage duration, which means that it lasts for the lifetime of the program in the case of a global, but when you're talking about a local, it means that it's zero initialized by default.

The C++ Standard says this for class data members with the keyword static:

3.7.1 Static storage duration [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.

What does it mean with local variable? Is that a function local variable? Because there's also that when you declare a function local as static that it is only initialized once, the first time it enters this function.

It also only talks about storage duration with regards to class members, what about it being non instance specific, that's also a property of static no? Or is that storage duration?

Now what about the case with static and file scope? Are all global variables considered to have static storage duration by default? The following (from section 3.7.1) seems to indicate so:

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)

How does static relate to the linkage of a variable?

This whole static keyword is downright confusing, can someone clarify the different uses for it English and also tell me when to initialize a static class member?

解决方案

Variables:

static variables exist for the "lifetime" of the translation unit that it's defined in, and:

  • If it's in a namespace scope (i.e. outside of functions and classes), then it can't be accessed from any other translation unit. This is known as "internal linkage". (Dont' do this in headers, it's just a terrible idea)
  • If it's a variable in a function, it can't be accessed from outside of the function, just like any other local variable. (this is the local they mentioned)
  • class members have no restricted scope due to static, but can be addressed from the class as well as an instance (like std::string::npos). [Note: you can declare static members in a class, but they should usually still be defined in a translation unit (cpp file), and as such, there's only one per class]

Before any function in a translation unit is executed (possibly after main began execution), the variables with static storage duration in that translation unit will be "constant initialized" (to constexpr where possible, or zero otherwise), and then non-locals are "dynamically initialized" properly in the order they are defined in the translation unit (for things like std::string="HI"; that aren't constexpr). Finally, function-local statics are initialized the first time execution "reaches" the line where they are declared. They are all destroyed in the reverse order of initialization.

The easiest way to get all this right is to make all static variables that are not constexpr initialized into function static locals, which makes sure all of your statics/globals are initialized properly when you try to use them no matter what, thus preventing the static initialization order fiasco.

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

Be careful, because when the spec says namespace-scope variables have "static storage duration" by default, they mean the "lifetime of the translation unit" bit, but that does not mean it can't be accessed outside of the file.

Functions

Significantly more straightforward, static is often used as a class member function, and only very rarely used for a free-standing function.

A static member function differs from a regular member function in that it can be called without an instance of a class, and since it has no instance, it cannot access non-static members of the class. Static variables are useful when you want to have a function for a class that definitely absolutely does not refer to any instance members, or for managing static member variables.

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
}

A static free-function means that the function will not be referred to by any other translation unit, and thus the linker can ignore it entirely. This has a small number of purposes:

  • Can be used in a cpp file to guarantee that the function is never used from any other file.
  • Can be put in a header and every file will have it's own copy of the function. Not useful, since inline does pretty much the same thing.
  • Speeds up link time by reducing work
  • Can put a function with the same name in each TU, and they can all do different things. For instance, you could put a static void log(const char*) {} in each cpp file, and they could each all log in a different way.

这篇关于static关键字及其在C ++中的各种用法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆