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…这很有趣。你知道如何防止类似的事情发生吗?:)我不能马上确定一个好的答案,但我知道已经有很多关于它的信息(这就是为什么我意识到它至少可能是一个问题)。:-]似乎特别相关。