Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.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++17 - Fatal编程技术网

C++ 启动时自动初始化库

C++ 启动时自动初始化库,c++,c++17,C++,C++17,我有一堆静态的init()方法,我需要在应用程序启动时调用它们。有点像必须要做的: A::init(); S::init(); //... 一种方法是初始化静态变量,如下所示: static bool const b{A::init(), S::init(), false}; 是否存在更好的替代方案?您可以使用startup类的实例来初始化其构造函数中的各种组件,并在其析构函数中终止它们。例如: struct Startup { Startup() { A::

我有一堆静态的
init()
方法,我需要在应用程序启动时调用它们。有点像必须要做的:

A::init();
S::init();
//...
一种方法是初始化静态变量,如下所示:

static bool const b{A::init(), S::init(), false};

是否存在更好的替代方案?

您可以使用startup类的实例来初始化其构造函数中的各种组件,并在其析构函数中终止它们。例如:

struct Startup
{
    Startup()
    {
        A::Init();
        B::Init();
    }
    ~Startup()
    {
        B::Term();
        A::Term();
    }
};

namespace { Startup startup; }

int main()
{
    // do stuff being completely oblivious to the startup
}

您可以使用
init\u dispatch
模板,该模板通过可变参数列表调用
init()

模板
结构分派
{
分派(){T::init();}
};
模板
struct init_分派:std::false_类型
,发送。。。
{
init_dispatch():dispatch{}…{}
};
静态bool const b=init_dispatch

我已经玩了好几次“主生活之前的生活”,直到意识到它通常比必要的更痛苦

因此,我的忠告是:

int main() {
    A::init();
    S::init();

    // ...
}
为了清楚起见,可能需要创建一个
init
函数,该函数将依次调用所有这些函数


除非各个库之间的依赖关系树非常清晰,否则我建议不要打包(即使用
B::init
调用
A::init
),因为在菱形依赖关系的情况下,可能会多次调用基本库
init

不要自动初始化。在
main
中启动时,显式初始化子系统

原因是:

  • 您可以控制初始化顺序
  • 如果初始化失败,您可以正确处理它
  • 如果初始化导致崩溃,那么调试会更容易,并且希望有一个正确的堆栈跟踪
  • 它确保您完全了解初始化过程

  • 就个人而言,我绝对建议保持简单:在
    main
    中初始化内容,而不是使用神奇的静态。这样,事情发生的时候是明确的,事情发生的时候也是明确的。您可以对应用程序发生前后的状态进行推理


    main
    之前和之后发生的任何事情都会导致故障。

    在应用程序关闭时,您有类似的(对称)操作要执行吗?@MatthieuM。不,我销毁了所有需要在析构函数和删除函数中销毁的内容。菱形是正确的,但是健壮的
    init()
    可以很好地处理多个调用。@ildjarn我不确定我是否理解这个问题。你对使用
    b
    有什么担心?如果从未使用过ODR,为什么链接器不优化它,从而实例化
    init\u dispatch
    ?@ildjarn-Hmm…这很有趣。你知道如何防止类似的事情发生吗?:)我不能马上确定一个好的答案,但我知道已经有很多关于它的信息(这就是为什么我意识到它至少可能是一个问题)。:-]似乎特别相关。