c ++中的静态变量定义顺序

时间:2010-06-09 08:45:04

标签: c++

您好我有一个类工具,它有静态变量std :: vector m_tools。

我可以将值插入到其他文件中定义的其他类的全局范围的静态变量中。

示例:

tools.h文件

class Tools
{
public:
static std::vector<std::vector> m_tools;

void print()
{
for(int i=0 i< m_tools.size() ; i++)
std::cout<<"Tools initialized :"<< m_tools[i];
}
}

tools.cpp文件

std::vector<std::vector> Tools::m_tools;  //Definition

使用寄存器类构造函数将新字符串插入静态变量。

class Register
{
public:
  Register(std::string str)
{
Tools::m_tools.pushback(str);
}

};

将字符串插入静态变量

中的静态变量的不同类

first_tool.cpp

//Global scope declare global register variable


Register a("first_tool");



////////

second_tool.cpp

//Global scope declare global register variable


Register a("second_tool");

Main.cpp的

void main()
{
Tools abc;
abc.print();
}

这会有用吗?

在上面的例子中,只有一个字符串被插入到静态列表中。问题看起来像“在全局范围内它尝试在定义完成之前插入元素” 请告诉我有没有办法设置静态定义优先级?或者有没有其他方法可以做同样的事情。

3 个答案:

答案 0 :(得分:3)

您可能会遇到称为初始化订单Fiasco的问题。

问题是全局变量(和静态类变量是全局变量)的初始化顺序在同一个翻译单元中很好地定义(粗略地认为是.cpp),但是在翻译单元中是完全未定义的。因此,当您尝试在那里推送项目时,无法保证向量被初始化。

你的解决方案在这里?使用本地静态变量:

class Tools
{
public:
  static std::vector<std::string>& AccessTools()
  {
    static std::vector<std::string> Tools; // local static
    return Tools;
  }
private:
};

class Register
{
public:
  Register(std::string str)
  {
    Tools::AccessTools().push_back(str);
  }

};

保证在第一次访问时初始化...虽然它不是(也不可能)线程安全的;如果您处于多线程情况,则需要在启动其他线程之前在Tools::AccessTools中调用main以保证初始化。

答案 1 :(得分:1)

不同编译单元中静态全局变量的初始化顺序未在C ++中定义 - 这就是您遇到问题的原因。

解决方法可能是调用包含第一个静态变量为local的静态函数。这样你就可以在使用之前强制它被初始化:

// tools.h

class Tools
{
public:
  static std::vector<std::vector>& getTools();
  ...
};

// tools.cpp

std::vector<std::vector>& Tools::getTools() {
  static std::vector<std::vector> tools;
  return tools;
}

...
class Register
{
public:
  Register(std::string str)
  {
    Tools::getTools().pushback(str);
  }
};

答案 2 :(得分:0)

C ++没有指定静态的初始化。 C++ FAQ Lite将其称为“static initialization order fiasco

MY2C