C ++字符串常量和静态初始化顺序惨败

时间:2019-02-07 08:53:32

标签: c++ c++11 static-initialization

我试图了解何时静态初始化顺序惨败是一个真正的问题。如果我在下面使用类似kName的字符串常量,它将遭受静态初始化顺序严重失败的任何问题吗?在这种情况下这是一个问题,因为可以像在Derived中一样初始化kName之前创建main.cpp的实例吗?

// Base.cpp
namespace test {
class Base {
public:
  virtual ~Base() = default;

protected:
  explicit Base(const std::string &name);
};
} // namespace test

// Derived.cpp
namespace test {
static const std::string kName = "my name";

class Derived : public Base {
public:
  Derived() : Base(kName) {}
  ~Derived() override = default;
};
} // namespace test

// main.cpp
int main() {
  test::Derived instance{};
  return 0;
}

2 个答案:

答案 0 :(得分:2)

在初始化所有“全局”变量之前,不会调用main函数。其中包括static个成员变量以及namespace范围内的变量(是否为static)。

因此在这种情况下,因为您在instance函数中定义了main,所以没问题。

如果在instance函数之外静态完成main的定义,将会有所不同。

答案 1 :(得分:2)

在特定的翻译单元中,静态对象的初始化顺序被保证为该翻译单元中对象定义出现的顺序。销毁顺序可以保证与初始化顺序相反。 但是,不能保证跨翻译单元的静态对象的初始化顺序。这就是所谓的静态初始化顺序失败。

因此,在这里您不会遇到静态初始化顺序的惨败。