Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;?_C++_Static Members_Lifetime - Fatal编程技术网

C++ C++;?

C++ C++;?,c++,static-members,lifetime,C++,Static Members,Lifetime,如果我有一个名为Test的类: class Test { static std::vector<int> staticVector; }; 类测试 { 静态std::向量staticVector; }; staticVector什么时候被构造,什么时候被破坏 它是通过测试类的第一个对象的实例化,还是像常规静态变量一样 为了澄清,在阅读了编程语言的概念(Sebesta Ch-5.4.3.1)之后,我想到了这个问题,它说: 请注意,当使用静态修改器 出现在 C++中类定义中的

如果我有一个名为Test的类:

class Test
{
    static std::vector<int> staticVector;
};
类测试
{
静态std::向量staticVector;
};
staticVector什么时候被构造,什么时候被破坏

它是通过测试类的第一个对象的实例化,还是像常规静态变量一样

为了澄清,在阅读了编程语言的概念(Sebesta Ch-5.4.3.1)之后,我想到了这个问题,它说:

请注意,当使用静态修改器 出现在 C++中类定义中的变量 Java和C#,它与 变量的生存期。因为 上下文,表示变量是 类变量,而不是 实例变量。多用途 保留字的名称可能会令人困惑 尤其是那些学习 语言


你明白了吗?:(

与常规静态(全局)变量完全相同。

它是在全局变量与全局变量一起构造和分解的同时构造的。

简单地说:
静态成员变量是在构造全局变量时构造的。全局变量的构造顺序没有定义,但发生在输入主函数之前

当全局变量被销毁时,就会发生销毁

在退出主函数后,全局变量按与构造顺序相反的顺序销毁

问候,
奥文斯

附言:我建议看一看C++标准,它解释(定义)如何以及何时构造或销毁全局或静态成员变量

p.p.S.:您的代码只声明一个静态成员变量,但不初始化它。要初始化它,您必须使用以下编译单元之一编写:

std::vector Test::staticVector;


std::vector Test::staticVector=std::vector(/*ctor参数在这里*/);

一些特定的VC++信息,以防您使用这些信息:

  • 静态类变量构造与其他静态/全局变量同时发生
  • 在windows中,CRT启动功能负责此构造。 这是您编译的大多数程序的实际入口点(它是调用Main/Winmain函数的函数)。 此外,它还负责初始化整个C运行时支持(例如,您需要它来使用malloc)
  • 构造顺序未定义,但是在使用microsoft VC编译器时,基本类型的构造顺序是可以确定的,例如,编写是合法和安全的
  • 静力学.h: …MyClass声明。。。 静态常数INTA; 静态int b; 静态int-ar[]; } statics.cpp:

    const int MyClass::a = 2;
    int MyClass::b = a+3;
    int MyClass::ar[a] = {1,2}
    

    我还想写一些关于初始化的文字,稍后可以链接到


    首先是可能性清单

    • 命名空间静态
    • 类静态
    • 局部静电
    命名空间静态
    • 有两种初始化方法。静态(打算在编译时发生)和动态(打算在运行时发生)初始化
    • 静态初始化发生在任何动态初始化之前,不考虑转换单元关系
    • 动态初始化在转换单元中是有序的,而静态初始化中没有特定的顺序。同一转换单元的命名空间范围的对象按照其定义出现的顺序进行动态初始化
    • 用常量表达式初始化的POD类型对象是静态初始化的。任何对象的动态初始化都可以依赖它们的值,而不考虑转换单元关系
    • 如果初始化引发异常,则调用
      std::terminate
    示例:

    以下程序打印A(1)A(2)

    struct A { 
      A(int n) { std::printf(" A(%d) ", n); } 
    };
    
    A a(1);
    A b(2);
    
    extern A a;
    A b(2);
    A a(1);
    
    下面,基于同一类,打印
    A(2)A(1)

    struct A { 
      A(int n) { std::printf(" A(%d) ", n); } 
    };
    
    A a(1);
    A b(2);
    
    extern A a;
    A b(2);
    A a(1);
    
    让我们假设有一个翻译单元,
    msg
    定义如下

    char const *msg = "abc";
    
    然后,下面打印出
    abc
    。请注意,
    p
    接收动态初始化。但是因为静态初始化(
    char const*
    是POD类型,
    “abc”
    是地址常量表达式)如果
    msg
    在这之前发生,则这是可以的,并且
    msg
    保证正确初始化

    extern const char *msg;
    struct P { P() { std::printf("%s", msg); } };
    P p;
    
    • 对象的动态初始化不需要不惜一切代价在main之前进行。但是,初始化必须在对象或其转换单元的函数首次使用之前进行。这对于动态可加载库非常重要
    类静态
    • 行为类似于名称空间静态
    • 关于是否允许编译器在首次使用其转换单元的函数或对象时(在main之后)初始化类静态,有一个错误报告。标准中的措辞目前仅允许命名空间范围对象使用此选项,但似乎它也打算允许类范围对象使用此选项。请阅读
    • 对于作为模板成员的类静态,规则是只有在使用它们时才会初始化。不使用它们不会导致初始化。请注意,在任何情况下,初始化都会像上面解释的那样进行。初始化不会因为是模板的成员而延迟
    局部静电
    • 对于局部静态,会出现特殊规则
    • 使用常量表达式初始化的POD类型对象在输入定义它们的块之前初始化
    • 其他本地静态对象在控件第一次通过其定义时初始化。当引发异常时,初始化不被视为完成。将在