gpt4 book ai didi

c++ - 如何等到静态变量的动态初始化完成

转载 作者:太空狗 更新时间:2023-10-29 23:09:12 25 4
gpt4 key购买 nike

根据其他资料,C++区分两种静态变量的初始化:

  • static - 如果变量是通过将其置于可执行文件中的特殊部分的初始值内来初始化的。

  • 动态 - 如果静态变量的初始值也已计算

关于动态初始化构造函数调用的顺序有很多讨论。但是我没有找到如何等待可执行文件中所有静态变量的所有动态初始化完成的信息。或者从另一端如何以间接/通用方式手动调用此初始化。

我使用静态变量初始化来实现插件架构的松散耦合。我在 plugin1.c 中有 plugin1.c、plugin2.c ... 和静态变量static bool installed = plugin1_install();

但在 main 中我需要等到所有插件都安装完毕。

这里建议我使用同样的东西 1 .作为以下问题的答案

I wanted to write a shared library for my program. However, I need the library to have some self initialization routines before anyother functions in the library are called...

回答:

C++ itself supports global initializations of things. You can do things like:

int global_variable=some_global_function();

This would be illegal in C, but is legal in C++.

我能否在 __CTOR_LIST__ 的帮助下实现我需要的功能?

最佳答案

无需等待。在 C++ 中,程序启动是单线程的,因此一旦您到达 main 的第一条指令,所有全局静态存储持续时间变量都将已经初始化。

然而,您读到的问题是,在启动阶段的初始化顺序几乎无法保证。换句话说,如果静态对象的初始化需要使用另一个静态对象,那么您可能会有麻烦。

我的建议是尽量避免在启动阶段进行复杂的处理……特别是避免做任何可能会失败的事情。原因是在此期间(以及在其双重关闭时间期间)系统尚未(或不再)100% 正常运行并且调试特别困难。例如,在 Windows 系统中,关闭期间的段错误通常会被消除,并且在某些环境中,调试在 main 开始之前无法正常工作。

如果您的初始化阶段只是插件注册,那么可以通过对注册表使用惰性单例模式来确保安全:

struct Plugin
{
Plugin(const std::string& name);
...
};

std::map<const char *, Plugin *>& registered_plugins()
{
static std::map<const char *, Plugin *> directory;
return directory;
}

Plugin::Plugin(const char * name)
{
registered_plugins()[name] = this;
}

...

struct MyPlugin1 : Plugin
{
MyPlugin1() : Plugin("Plugin-1")
...
} MyPlugin_instance;

在上面的代码中,MyPlugin_instance 变量将在启动期间(在 main 之前)创建,但已知插件注册表已经正确构建,因为它不是全局的,而是一个静态函数,这些变量在第一次进入它们的范围时被初始化。

将全局插件目录声明为静态持续时间全局会出现问题,因为如果插件和目录不在同一编译单元中,则无法保证初始化顺序;因此,插件有可能被构建并尝试在尚未构建的 map 中注册自己。

然而,这种方法仍然存在危险的是在静态持续时间对象的析构函数中访问单例,因为 - 就像构造一样 - 风险是有人会在注册表已经被销毁后尝试使用它。

无论如何,我的建议是尽量将这种预主处理保持在最低限度;任何不平凡的事情都可能成为大问题和难以调试的问题的根源。如果可能的话,启动和关闭应该由 IMO 保持在明确的控制和单线程下。

关于c++ - 如何等到静态变量的动态初始化完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6234791/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com