2

我有一堆静态init()方法,需要在应用程序启动时调用。有点像不得不这样做:

A::init();
S::init();
//...

一种方法是像这样初始化一个静态变量:

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

有没有更好的选择?

4

5 回答 5

3

不要自动初始化。在main.

原因是:

  1. 可以控制初始化顺序
  2. 如果初始化失败,可以妥善处理
  3. 如果初始化导致崩溃,您将可以更轻松地进行调试,并希望获得正确的堆栈跟踪
  4. 它确保您完全了解初始化过程
于 2015-01-02T16:22:05.483 回答
3

我已经玩了很多次“生活之前的生活”,然后才意识到它通常比必要的更痛苦。

因此,我的建议是:

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

    // ...
}

为清楚起见,可能值得创建一个init依次调用所有这些函数的函数。

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

于 2015-01-02T16:18:55.627 回答
3

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

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
}
于 2015-01-02T16:08:28.687 回答
1

就个人而言,我绝对建议保持简单:初始化内部的东西main,而不是使用魔法静态。这样一来,它的发生就很明确了,它发生的时候也很明确。您可以推断应用程序发生前后的状态。

之前和之后发生的任何事情main都只会导致麻烦。

于 2015-01-02T16:24:24.330 回答
1

您可以拥有一个通过可变参数列表init_dispatch调用的模板:init()

template<typename T>
struct dispatch
{
    dispatch() { T::init(); }
};

template<typename... Ts>
struct init_dispatch : std::false_type
                     , dispatch<Ts>...
{
    init_dispatch() : dispatch<Ts>{}... {}
};

static bool const b = init_dispatch<A, S>{}.value;

Demo

于 2015-01-02T16:12:35.570 回答