什么时候初始化静态C++类成员?

z0qdvdin  于 2023-05-02  发布在  其他
关注(0)|答案(7)|浏览(146)

这个问题似乎没有简单的答案,但是对于何时可以访问静态类字段,是否可以安全地做出任何假设?
编辑:唯一安全的假设似乎是所有的静态数据在程序开始之前就被初始化了(调用main)。所以,只要我不引用其他静态初始化代码中的静态数据,就没有什么可担心的了?

70gysomp

70gysomp1#

该标准保证了两件事--在同一个翻译单元中定义的对象(通常它的意思是。cpp文件)按照定义的顺序初始化(不是声明):
3.6.2
具有静态存储持续时间的对象的存储(基本。stc.static)将被零初始化(dcl.init)之前进行任何其他初始化。零初始化和用常量表达式初始化统称为静态初始化;所有其它初始化是动态初始化。POD类型的对象(基本。类型),静态存储持续时间用常量表达式(expr.const)将在任何动态初始化发生之前被初始化。在同一个翻译单元的命名空间范围内定义了静态存储期限并动态初始化的对象,应按照其定义在翻译单元中出现的顺序进行初始化。
另一个可以保证的事情是,在使用来自翻译单元的任何对象或函数之前,将完成来自翻译单元的静态对象的初始化:
动态初始化(dcl.初始化,类。静态,类。老师同学们expl.init)在main的第一个语句之前完成。如果初始化被推迟到main的第一个语句之后的某个时间点,则它应在首次使用与要初始化的对象相同的翻译单元中定义的任何函数或对象之前发生。
没有其他保证(特别是在不同翻译单元中定义的对象的初始化顺序是实现定义的)。

wdebmtf2

wdebmtf22#

它们在程序启动之前被初始化(即即在输入main之前)。
当一个CPP文件中有两个或多个定义(静态数据)时,它们将按照在文件中定义的顺序进行初始化(文件中较早/较高定义的定义将在下一个定义之前进行初始化)。
当在多个CPP文件中有两个或多个(静态数据的)定义时,处理CPP文件的顺序是未定义的/特定于实现的。如果一个全局变量的构造函数(在程序启动前调用)引用了另一个在不同CPP文件中定义的全局变量,这可能还没有被构造,这就是一个问题。然而,Meyers的 Effective C++ 中的第47条(标题为 * 确保全局对象在使用前被初始化 *)确实描述了一种变通方法。..

  • 在头文件中定义一个静态变量(它是静态的,所以你可以有它的多个示例,而链接器不会抱怨)
  • 让该变量的构造函数调用您需要的任何内容(特别是,构造在头文件中声明的全局单例)

...它说这是一种技术,可用于某些系统头文件e.例如,确保cin全局变量在静态变量的构造函数使用它之前被初始化。

vfwfrxfs

vfwfrxfs3#

你在编辑中的最终结论是正确的。但问题是类本身是静态的。更容易说的是,我的代码将有不引用其他全局数据/类静态成员的类静态成员,但一旦你采取这种方式,事情很快就会出错。我发现在实践中有用的一种方法是不使用类静态数据成员,而是使用类静态 Package 方法。然后这些方法可以将静态对象保存在其自身中。例如``
`

TypeX* Class2::getClass1Instance()
{
    static TypeX obj1;
    return &obj1;
}

`
``注:早先的回答说:
另一个可以保证的事情是,在使用来自翻译单元的任何对象或函数之前,将完成来自翻译单元的静态对象的初始化
这是不完全正确的,这里的标准是不正确的推断。如果在输入main之前调用来自转换单元的函数,则这可能不成立。

apeeds0o

apeeds0o4#

我相信在行刑过程中随时都可以进入。仍然未定义的是静态变量的初始化顺序。

ws51t4hk

ws51t4hk5#

它们可以在实现文件(。c/cpp/cc)文件。不要在中初始化它们。h作为编译器将抱怨多个定义。
它们通常在main之前初始化,但是顺序未知,因此避免了依赖性。它们当然可以在成员函数中访问。请记住,静态成员的初始化顺序是未知的。我建议将静态成员封装到静态函数中,该函数将检查成员是否已初始化。

kmynzznz

kmynzznz6#

对于这个问题没有一个完全无关紧要的答案,但基本上它们是在控制传递到程序的入口点(main)之前初始化的。它们初始化的顺序(据我所知)是未定义的,可能是编译器特定的。
编辑:澄清一下,你的假设是正确的。只要你只是在主条目后访问它,你就不必担心它何时/如何初始化。它将在那个时候被初始化。

3htmauhk

3htmauhk7#

我认为一个进程的主线程将按顺序执行以下五个步骤

  1. CRT库初始化
    1.静态初始化
  2. main()函数的执行
    1.静态单位化
    1.阴极射线管库单元化
    你想从其他静态初始化代码中引用静态数据吗?下面的代码可能会起作用:
class A;
static auto_ptr<A> a(auto_ptr<A>(&GetStaticA()));
A &GetStaticA(void)
{
    static A *a = NULL; //the static basic type variables initialized with constant experession will be initialized earlier than the other static ones
    if (a == NULL)
    {
         a = new A();
         return *a;
    }
}

相关问题